Change ServiceType to a sealed class from an abstract class

Allow AdvertisedServices to have their own identity and keys. Also, rationalise legalIdentity onto the local node's NodeInfo which is available on ServiceHub

Fixup after rebase

Remove legal identity that was on storage service. Now access via myInfo.legalIdentity and key via keyManagement lookup.

Enforce singleton notary per node for now

Tidy up based upon Rick's suggestions

Handle PR comments

clean up imports

Fix typo

Fixup rename

Capitalise comment

Eliminate unused variable warning

Make changes based upon PR comments

Cleanup whitespace changes
This commit is contained in:
Matthew Nesbit
2016-10-04 14:04:52 +01:00
parent 4e2f0e0ff9
commit 1e836edd78
64 changed files with 463 additions and 325 deletions

View File

@ -44,7 +44,7 @@ class NodeMonitorModelTest {
thread { thread {
driver { driver {
val aliceNodeFuture = startNode("Alice") 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() aliceNode = aliceNodeFuture.get()
notaryNode = notaryNodeFuture.get() notaryNode = notaryNodeFuture.get()
@ -79,8 +79,8 @@ class NodeMonitorModelTest {
clientToService.onNext(ClientToServiceCommand.IssueCash( clientToService.onNext(ClientToServiceCommand.IssueCash(
amount = Amount(100, USD), amount = Amount(100, USD),
issueRef = OpaqueBytes(ByteArray(1, { 1 })), issueRef = OpaqueBytes(ByteArray(1, { 1 })),
recipient = aliceNode.identity, recipient = aliceNode.legalIdentity,
notary = notaryNode.identity notary = notaryNode.notaryIdentity
)) ))
vaultUpdates.expectEvents(isStrict = false) { vaultUpdates.expectEvents(isStrict = false) {
@ -105,13 +105,13 @@ class NodeMonitorModelTest {
clientToService.onNext(ClientToServiceCommand.IssueCash( clientToService.onNext(ClientToServiceCommand.IssueCash(
amount = Amount(100, USD), amount = Amount(100, USD),
issueRef = OpaqueBytes(ByteArray(1, { 1 })), issueRef = OpaqueBytes(ByteArray(1, { 1 })),
recipient = aliceNode.identity, recipient = aliceNode.legalIdentity,
notary = notaryNode.identity notary = notaryNode.notaryIdentity
)) ))
clientToService.onNext(ClientToServiceCommand.PayCash( clientToService.onNext(ClientToServiceCommand.PayCash(
amount = Amount(100, Issued(PartyAndReference(aliceNode.identity, OpaqueBytes(ByteArray(1, { 1 }))), USD)), amount = Amount(100, Issued(PartyAndReference(aliceNode.legalIdentity, OpaqueBytes(ByteArray(1, { 1 }))), USD)),
recipient = aliceNode.identity recipient = aliceNode.legalIdentity
)) ))
var issueSmId: StateMachineRunId? = null var issueSmId: StateMachineRunId? = null
@ -146,7 +146,7 @@ class NodeMonitorModelTest {
val signaturePubKeys = tx.sigs.map { it.by }.toSet() val signaturePubKeys = tx.sigs.map { it.by }.toSet()
// Only Alice signed // Only Alice signed
require(signaturePubKeys.size == 1) require(signaturePubKeys.size == 1)
require(signaturePubKeys.contains(aliceNode.identity.owningKey)) require(signaturePubKeys.contains(aliceNode.legalIdentity.owningKey))
issueTx = tx issueTx = tx
}, },
// MOVE // MOVE
@ -156,8 +156,8 @@ class NodeMonitorModelTest {
val signaturePubKeys = tx.sigs.map { it.by }.toSet() val signaturePubKeys = tx.sigs.map { it.by }.toSet()
// Alice and Notary signed // Alice and Notary signed
require(signaturePubKeys.size == 2) require(signaturePubKeys.size == 2)
require(signaturePubKeys.contains(aliceNode.identity.owningKey)) require(signaturePubKeys.contains(aliceNode.legalIdentity.owningKey))
require(signaturePubKeys.contains(notaryNode.identity.owningKey)) require(signaturePubKeys.contains(notaryNode.notaryIdentity.owningKey))
moveTx = tx moveTx = tx
} }
) )

View File

@ -188,7 +188,9 @@ class FloatingRatePaymentEvent(date: LocalDate,
class InterestRateSwap() : Contract { class InterestRateSwap() : Contract {
override val legalContractReference = SecureHash.sha256("is_this_the_text_of_the_contract ? TBD") 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. * 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 contract = IRS_PROGRAM_ID
override val oracleType: ServiceType override val oracleType: ServiceType
get() = OracleType get() = InterestRateSwap.oracleType
override val ref = common.tradeID override val ref = common.tradeID

View File

@ -37,7 +37,7 @@ fun ServiceHub.fillWithSomeTestCash(howMuch: Amount<Currency>,
ownedBy: PublicKey? = null): Vault { ownedBy: PublicKey? = null): Vault {
val amounts = calculateRandomlySizedAmounts(howMuch, atLeastThisManyStates, atMostThisManyStates, rng) 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. // We will allocate one state to one transaction, for simplicities sake.
val cash = Cash() val cash = Cash()

View File

@ -8,6 +8,7 @@ import com.r3corda.core.crypto.DigitalSignature
import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.Party
import com.r3corda.core.crypto.signWithECDSA import com.r3corda.core.crypto.signWithECDSA
import com.r3corda.core.node.NodeInfo import com.r3corda.core.node.NodeInfo
import com.r3corda.core.node.services.ServiceType
import com.r3corda.core.protocols.ProtocolLogic import com.r3corda.core.protocols.ProtocolLogic
import com.r3corda.core.seconds import com.r3corda.core.seconds
import com.r3corda.core.transactions.SignedTransaction import com.r3corda.core.transactions.SignedTransaction
@ -113,7 +114,7 @@ object TwoPartyTradeProtocol {
progressTracker.nextStep() progressTracker.nextStep()
// Check that the tx proposed by the buyer is valid. // 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}" } 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, // Download and check all the things that this transaction depends on and verify it is contract-valid,

View File

@ -211,7 +211,7 @@ class CommercialPaperTestsGeneric {
// BigCorp™ issues $10,000 of commercial paper, to mature in 30 days, owned initially by itself. // 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 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 = val issueTX: SignedTransaction =
CommercialPaper().generateIssue(issuance, faceValue, TEST_TX_TIME + 30.days, DUMMY_NOTARY).apply { CommercialPaper().generateIssue(issuance, faceValue, TEST_TX_TIME + 30.days, DUMMY_NOTARY).apply {
setTime(TEST_TX_TIME, 30.seconds) setTime(TEST_TX_TIME, 30.seconds)

View File

@ -3,10 +3,21 @@ package com.r3corda.core.node
import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.Party
import com.r3corda.core.messaging.SingleMessageRecipient import com.r3corda.core.messaging.SingleMessageRecipient
import com.r3corda.core.node.services.ServiceInfo 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. * Info about a network node that acts on behalf of some form of contract party.
*/ */
data class NodeInfo(val address: SingleMessageRecipient, val identity: Party, data class NodeInfo(val address: SingleMessageRecipient,
var advertisedServices: Set<ServiceInfo> = emptySet(), val legalIdentity: Party,
val physicalLocation: PhysicalLocation? = null) var advertisedServices: List<ServiceEntry> = emptyList(),
val physicalLocation: PhysicalLocation? = null) {
val notaryIdentity: Party get() = advertisedServices.single { it.info.type.isNotary() }.identity
fun serviceIdentities(type: ServiceType): List<Party> = advertisedServices.filter { it.info.type.isSubTypeOf(type) }.map { it.identity }
}

View File

@ -8,6 +8,7 @@ import com.r3corda.core.contracts.TransactionState
import com.r3corda.core.messaging.MessagingService import com.r3corda.core.messaging.MessagingService
import com.r3corda.core.node.services.* import com.r3corda.core.node.services.*
import com.r3corda.core.protocols.ProtocolLogic import com.r3corda.core.protocols.ProtocolLogic
import java.security.KeyPair
import java.time.Clock import java.time.Clock
/** /**
@ -27,6 +28,7 @@ interface ServiceHub {
val networkMapCache: NetworkMapCache val networkMapCache: NetworkMapCache
val schedulerService: SchedulerService val schedulerService: SchedulerService
val clock: Clock val clock: Clock
val myInfo: NodeInfo
/** /**
* Given a list of [SignedTransaction]s, writes them to the local storage for validated transactions and then * 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]. * @throws IllegalProtocolLogicException or IllegalArgumentException if there are problems with the [logicType] or [args].
*/ */
fun <T : Any> invokeProtocolAsync(logicType: Class<out ProtocolLogic<T>>, vararg args: Any?): ListenableFuture<T> fun <T : Any> invokeProtocolAsync(logicType: Class<out ProtocolLogic<T>>, vararg args: Any?): ListenableFuture<T>
/**
* 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 * Given some [SignedTransaction]s, writes them to the local storage for validated transactions and then

View File

@ -3,7 +3,7 @@ package com.r3corda.core.node.services
/** /**
* A container for additional information for an advertised service. * 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 * @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. * 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 { fun parse(encoded: String): ServiceInfo {
val parts = encoded.split("|") val parts = encoded.split("|")
require(parts.size > 0 && parts.size <= 2) { "Invalid number of elements found" } require(parts.size > 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) val name = parts.getOrNull(1)
return ServiceInfo(type, name) return ServiceInfo(type, name)
} }

View File

@ -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 * 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. * don't need a declared service type.
*/ */
abstract class ServiceType(val id: String) { sealed class ServiceType(val id: String) {
init { init {
// Enforce: // Enforce:
// //
@ -14,14 +14,41 @@ abstract class ServiceType(val id: String) {
require(id.matches(Regex("[a-z][a-zA-Z0-9._]+"))) require(id.matches(Regex("[a-z][a-zA-Z0-9._]+")))
} }
override operator fun equals(other: Any?): Boolean = private class ServiceTypeImpl(baseId: String, subTypeId: String) : ServiceType("$baseId.$subTypeId") {
if (other is ServiceType) { init {
id == other.id // only allowed one level of subtype
} else { require(subTypeId.matches(Regex("[a-z]\\w+")))
false }
} }
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 isSubTypeOf(superType: ServiceType) = (id == superType.id) || id.startsWith(superType.id + ".")
fun isNotary() = isSubTypeOf(notary)
override fun hashCode(): Int = id.hashCode() override fun hashCode(): Int = id.hashCode()
override fun toString(): String = id.toString() override fun toString(): String = id.toString()

View File

@ -191,14 +191,6 @@ interface StorageService {
val attachments: AttachmentStorage val attachments: AttachmentStorage
val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage 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
} }
/** /**

View File

@ -52,7 +52,7 @@ abstract class AbstractStateReplacementProtocol<T> {
progressTracker.currentStep = SIGNING progressTracker.currentStep = SIGNING
val myKey = serviceHub.storageService.myLegalIdentity.owningKey val myKey = serviceHub.myInfo.legalIdentity.owningKey
val me = listOf(myKey) val me = listOf(myKey)
val signatures = if (participants == me) { val signatures = if (participants == me) {
@ -74,7 +74,7 @@ abstract class AbstractStateReplacementProtocol<T> {
val parties = participants.map { val parties = participants.map {
val participantNode = serviceHub.networkMapCache.getNodeByPublicKey(it) ?: val participantNode = serviceHub.networkMapCache.getNodeByPublicKey(it) ?:
throw IllegalStateException("Participant $it to state $originalState not found on the network") throw IllegalStateException("Participant $it to state $originalState not found on the network")
participantNode.identity participantNode.legalIdentity
} }
val participantSignatures = parties.map { getParticipantSignature(it, stx) } val participantSignatures = parties.map { getParticipantSignature(it, stx) }
@ -134,7 +134,7 @@ abstract class AbstractStateReplacementProtocol<T> {
// TODO: catch only specific exceptions. However, there are numerous validation exceptions // TODO: catch only specific exceptions. However, there are numerous validation exceptions
// that might occur (tx validation/resolution, invalid proposal). Need to rethink how // that might occur (tx validation/resolution, invalid proposal). Need to rethink how
// we manage exceptions and maybe introduce some platform exception hierarchy // 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 state = maybeProposal.unwrap { it.stateRef }
val reason = StateReplacementRefused(myIdentity, state, e.message) val reason = StateReplacementRefused(myIdentity, state, e.message)
@ -186,7 +186,7 @@ abstract class AbstractStateReplacementProtocol<T> {
private fun checkMySignatureRequired(tx: WireTransaction) { private fun checkMySignatureRequired(tx: WireTransaction) {
// TODO: use keys from the keyManagementService instead // 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}" } 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<T> {
subProtocol(ResolveTransactionsProtocol(stx.tx, otherSide)) 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 // TODO: similar classes occur in other places (NotaryProtocol), need to consolidate

View File

@ -34,7 +34,7 @@ class BroadcastTransactionProtocol(val notarisedTransaction: SignedTransaction,
// TODO: Messaging layer should handle this broadcast for us // TODO: Messaging layer should handle this broadcast for us
val msg = NotifyTxRequest(notarisedTransaction, events) val msg = NotifyTxRequest(notarisedTransaction, events)
participants.filter { it != serviceHub.storageService.myLegalIdentity }.forEach { participant -> participants.filter { it != serviceHub.myInfo.legalIdentity }.forEach { participant ->
send(participant, msg) send(participant, msg)
} }
} }

View File

@ -41,7 +41,8 @@ object NotaryChangeProtocol: AbstractStateReplacementProtocol<Party>() {
val newState = state.withNotary(modification) val newState = state.withNotary(modification)
val participants = state.data.participants val participants = state.data.participants
val tx = TransactionType.NotaryChange.Builder(originalState.state.notary).withItems(originalState, newState) 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) val stx = tx.toSignedTransaction(false)
return Pair(stx, participants) return Pair(stx, participants)
@ -63,7 +64,7 @@ object NotaryChangeProtocol: AbstractStateReplacementProtocol<Party>() {
override fun verifyProposal(maybeProposal: UntrustworthyData<AbstractStateReplacementProtocol.Proposal<Party>>): AbstractStateReplacementProtocol.Proposal<Party> { override fun verifyProposal(maybeProposal: UntrustworthyData<AbstractStateReplacementProtocol.Proposal<Party>>): AbstractStateReplacementProtocol.Proposal<Party> {
return maybeProposal.unwrap { proposal -> return maybeProposal.unwrap { proposal ->
val newNotary = proposal.modification 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 " } require(isNotary) { "The proposed node $newNotary does not run a Notary service " }
val state = proposal.stateRef val state = proposal.stateRef

View File

@ -49,7 +49,7 @@ object NotaryProtocol {
"Input states must have the same Notary" "Input states must have the same Notary"
} }
val request = SignRequest(stx, serviceHub.storageService.myLegalIdentity) val request = SignRequest(stx, serviceHub.myInfo.legalIdentity)
val response = sendAndReceive<Result>(notaryParty, request) val response = sendAndReceive<Result>(notaryParty, request)
return validateResponse(response) return validateResponse(response)
@ -141,8 +141,9 @@ object NotaryProtocol {
} }
private fun <T : Any> sign(bits: SerializedBytes<T>): DigitalSignature.LegallyIdentifiable { private fun <T : Any> sign(bits: SerializedBytes<T>): DigitalSignature.LegallyIdentifiable {
val mySigningKey = serviceHub.storageService.myLegalIdentityKey val myNodeInfo = serviceHub.myInfo
val myIdentity = serviceHub.storageService.myLegalIdentity val myIdentity = myNodeInfo.notaryIdentity
val mySigningKey = serviceHub.notaryIdentityKey
return mySigningKey.signWithECDSA(bits, myIdentity) return mySigningKey.signWithECDSA(bits, myIdentity)
} }
} }

View File

@ -78,7 +78,7 @@ object TwoPartyDealProtocol {
abstract val myKeyPair: KeyPair abstract val myKeyPair: KeyPair
override fun getCounterpartyMarker(party: Party): Class<*> { 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 MarkerForBogusRegulatorProtocol::class.java
} else { } else {
super.getCounterpartyMarker(party) super.getCounterpartyMarker(party)
@ -104,7 +104,7 @@ object TwoPartyDealProtocol {
progressTracker.nextStep() progressTracker.nextStep()
// Check that the tx proposed by the buyer is valid. // 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}" } logger.trace { "Received partially signed transaction: ${stx.id}" }
checkDependencies(stx) checkDependencies(stx)
@ -155,7 +155,7 @@ object TwoPartyDealProtocol {
if (regulators.isNotEmpty()) { if (regulators.isNotEmpty()) {
// Copy the transaction to every regulator in the network. This is obviously completely bogus, it's // Copy the transaction to every regulator in the network. This is obviously completely bogus, it's
// just for demo purposes. // just for demo purposes.
regulators.forEach { send(it.identity, fullySigned) } regulators.forEach { send(it.serviceIdentities(ServiceType.regulator).first(), fullySigned) }
} }
return fullySigned return fullySigned
@ -277,7 +277,7 @@ object TwoPartyDealProtocol {
override val progressTracker: ProgressTracker = Primary.tracker()) : Primary() { override val progressTracker: ProgressTracker = Primary.tracker()) : Primary() {
override val notaryNode: NodeInfo get() = 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 // And add a request for timestamping: it may be that none of the contracts need this! But it can't hurt
// to have one. // to have one.
ptx.setTime(serviceHub.clock.instant(), 30.seconds) 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. // 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 // 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 // Also check we are one of the parties
deal.parties.filter { it.name == myName }.single() deal.parties.filter { it.name == myName }.single()
@ -339,7 +339,7 @@ object TwoPartyDealProtocol {
val fixOf = deal.nextFixingOf()!! val fixOf = deal.nextFixingOf()!!
// TODO Do we need/want to substitute in new public keys for the Parties? // 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 myOldParty = deal.parties.single { it.name == myName }
val newDeal = deal val newDeal = deal
@ -348,7 +348,7 @@ object TwoPartyDealProtocol {
val oracle = serviceHub.networkMapCache.get(handshake.payload.oracleType).first() 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 @Suspendable
override fun beforeSigning(fix: Fix) { override fun beforeSigning(fix: Fix) {
newDeal.generateFix(ptx, StateAndRef(txState, handshake.payload.ref), fix) newDeal.generateFix(ptx, StateAndRef(txState, handshake.payload.ref), fix)
@ -381,13 +381,13 @@ object TwoPartyDealProtocol {
} }
override val myKeyPair: KeyPair get() { 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 val publicKey = dealToFix.state.data.parties.filter { it.name == myName }.single().owningKey
return serviceHub.keyManagementService.toKeyPair(publicKey) return serviceHub.keyManagementService.toKeyPair(publicKey)
} }
override val notaryNode: NodeInfo get() = 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 // TODO: this is not the eventual mechanism for identifying the parties
val fixableDeal = (dealToFix.data as FixableDealState) val fixableDeal = (dealToFix.data as FixableDealState)
val sortedParties = fixableDeal.parties.sortedBy { it.name } 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) val fixing = FixingSession(ref, fixableDeal.oracleType)
// Start the Floater which will then kick-off the Fixer // Start the Floater which will then kick-off the Fixer
subProtocol(Floater(sortedParties[1], fixing)) subProtocol(Floater(sortedParties[1], fixing))

View File

@ -38,7 +38,7 @@ class ValidatingNotaryProtocol(otherSide: Party,
private fun checkSignatures(stx: SignedTransaction) { private fun checkSignatures(stx: SignedTransaction) {
try { try {
stx.verifySignatures(serviceHub.storageService.myLegalIdentity.owningKey) stx.verifySignatures(serviceHub.myInfo.legalIdentity.owningKey)
} catch(e: SignedTransaction.SignaturesMissingException) { } catch(e: SignedTransaction.SignaturesMissingException) {
throw NotaryException(NotaryError.SignaturesMissing(e.missing)) throw NotaryException(NotaryError.SignaturesMissing(e.missing))
} }

View File

@ -7,7 +7,7 @@ import kotlin.test.assertEquals
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
class ServiceInfoTests { class ServiceInfoTests {
val serviceType = object : ServiceType("corda.service.subservice") {} val serviceType = ServiceType.getServiceType("test", "service").getSubType("subservice")
val name = "service.name" val name = "service.name"
@Test @Test

View File

@ -32,7 +32,7 @@ class ResolveTransactionsProtocolTest {
val nodes = net.createSomeNodes() val nodes = net.createSomeNodes()
a = nodes.partyNodes[0] a = nodes.partyNodes[0]
b = nodes.partyNodes[1] b = nodes.partyNodes[1]
notary = nodes.notaryNode.info.identity notary = nodes.notaryNode.info.notaryIdentity
net.runNetwork() net.runNetwork()
} }
@ -44,7 +44,7 @@ class ResolveTransactionsProtocolTest {
@Test @Test
fun `resolve from two hashes`() { fun `resolve from two hashes`() {
val (stx1, stx2) = makeTransactions() 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) val future = b.services.startProtocol("resolve", p)
net.runNetwork() net.runNetwork()
val results = future.get() val results = future.get()
@ -56,7 +56,7 @@ class ResolveTransactionsProtocolTest {
@Test @Test
fun `dependency with an error`() { fun `dependency with an error`() {
val stx = makeTransactions(signFirstTX = false).second 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) val future = b.services.startProtocol("resolve", p)
net.runNetwork() net.runNetwork()
assertFailsWith(SignatureException::class) { assertFailsWith(SignatureException::class) {
@ -67,7 +67,7 @@ class ResolveTransactionsProtocolTest {
@Test @Test
fun `resolve from a signed transaction`() { fun `resolve from a signed transaction`() {
val (stx1, stx2) = makeTransactions() 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) val future = b.services.startProtocol("resolve", p)
net.runNetwork() net.runNetwork()
future.get() future.get()
@ -89,7 +89,7 @@ class ResolveTransactionsProtocolTest {
a.services.recordTransactions(stx) a.services.recordTransactions(stx)
cursor = stx cursor = stx
} }
val p = ResolveTransactionsProtocol(setOf(cursor.id), a.info.identity) val p = ResolveTransactionsProtocol(setOf(cursor.id), a.info.legalIdentity)
p.transactionCountLimit = 40 p.transactionCountLimit = 40
val future = b.services.startProtocol("resolve", p) val future = b.services.startProtocol("resolve", p)
net.runNetwork() net.runNetwork()
@ -116,7 +116,7 @@ class ResolveTransactionsProtocolTest {
a.services.recordTransactions(stx2, stx3) 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) val future = b.services.startProtocol("resolve", p)
net.runNetwork() net.runNetwork()
future.get() future.get()
@ -126,7 +126,7 @@ class ResolveTransactionsProtocolTest {
fun attachment() { fun attachment() {
val id = a.services.storageService.attachments.importAttachment("Some test file".toByteArray().opaque().open()) val id = a.services.storageService.attachments.importAttachment("Some test file".toByteArray().opaque().open())
val stx2 = makeTransactions(withAttachment = id).second 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) val future = b.services.startProtocol("resolve", p)
net.runNetwork() net.runNetwork()
future.get() future.get()

View File

@ -37,22 +37,22 @@ class Main : App() {
driver(portAllocation = portAllocation) { driver(portAllocation = portAllocation) {
val aliceNodeFuture = startNode("Alice") 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 aliceNode = aliceNodeFuture.get()
val notaryNode = notaryNodeFuture.get() val notaryNode = notaryNodeFuture.get()
val aliceClient = startClient(aliceNode).get() val aliceClient = startClient(aliceNode).get()
Models.get<IdentityModel>(Main::class).myIdentity.set(aliceNode.identity) Models.get<IdentityModel>(Main::class).myIdentity.set(aliceNode.legalIdentity)
Models.get<NodeMonitorModel>(Main::class).register(aliceNode, aliceClient.config.certificatesPath) Models.get<NodeMonitorModel>(Main::class).register(aliceNode, aliceClient.config.certificatesPath)
for (i in 0 .. 10000) { for (i in 0 .. 10000) {
Thread.sleep(500) Thread.sleep(500)
val eventGenerator = EventGenerator( val eventGenerator = EventGenerator(
parties = listOf(aliceNode.identity), parties = listOf(aliceNode.legalIdentity),
notary = notaryNode.identity notary = notaryNode.notaryIdentity
) )
eventGenerator.clientToServiceCommandGenerator.map { command -> eventGenerator.clientToServiceCommandGenerator.map { command ->

View File

@ -236,7 +236,7 @@ class NetworkMapVisualiser : Application() {
if (change.tracker == tracker) { if (change.tracker == tracker) {
// Protocol done; schedule it for removal in a few seconds. We batch them up to make nicer // Protocol done; schedule it for removal in a few seconds. We batch them up to make nicer
// animations. // animations.
println("Protocol done for ${node.info.identity.name}") println("Protocol done for ${node.info.legalIdentity.name}")
viewModel.doneTrackers += tracker viewModel.doneTrackers += tracker
} else { } else {
// Subprotocol is done; ignore it. // Subprotocol is done; ignore it.
@ -244,7 +244,7 @@ class NetworkMapVisualiser : Application() {
} else if (!viewModel.trackerBoxes.containsKey(tracker)) { } else if (!viewModel.trackerBoxes.containsKey(tracker)) {
// New protocol started up; add. // New protocol started up; add.
val extraLabel = viewModel.simulation.extraNodeLabels[node] 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) val widget = view.buildProgressTrackerWidget(label, tracker.topLevelTracker)
bindProgressTracketWidget(tracker.topLevelTracker, widget) bindProgressTracketWidget(tracker.topLevelTracker, widget)
println("Added: ${tracker}, ${widget}") println("Added: ${tracker}, ${widget}")

View File

@ -85,7 +85,7 @@ class VisualiserViewModel {
try { try {
return node.place.coordinate.project(view.mapImage.fitWidth, view.mapImage.fitHeight, 64.3209, 29.8406, -23.2031, 33.0469) return node.place.coordinate.project(view.mapImage.fitWidth, view.mapImage.fitHeight, 64.3209, 29.8406, -23.2031, 33.0469)
} catch(e: Exception) { } catch(e: Exception) {
throw Exception("Cannot project ${node.info.identity}", e) throw Exception("Cannot project ${node.info.legalIdentity}", e)
} }
} }

View File

@ -16,7 +16,7 @@ class DriverTests {
// Check that the node is registered in the network map // Check that the node is registered in the network map
poll("network map cache for $nodeName") { poll("network map cache for $nodeName") {
networkMapCache.get().firstOrNull { networkMapCache.get().firstOrNull {
it.identity.name == nodeName it.legalIdentity.name == nodeName
} }
} }
// Check that the port is bound // Check that the port is bound
@ -33,8 +33,8 @@ class DriverTests {
@Test @Test
fun simpleNodeStartupShutdownWorks() { fun simpleNodeStartupShutdownWorks() {
val (notary, regulator) = driver { val (notary, regulator) = driver {
val notary = startNode("TestNotary", setOf(ServiceInfo(SimpleNotaryService.Type))) val notary = startNode("TestNotary", setOf(ServiceInfo(SimpleNotaryService.type)))
val regulator = startNode("Regulator", setOf(ServiceInfo(RegulatorService.Type))) val regulator = startNode("Regulator", setOf(ServiceInfo(RegulatorService.type)))
nodeMustBeUp(networkMapCache, notary.get(), "TestNotary") nodeMustBeUp(networkMapCache, notary.get(), "TestNotary")
nodeMustBeUp(networkMapCache, regulator.get(), "Regulator") nodeMustBeUp(networkMapCache, regulator.get(), "Regulator")

View File

@ -77,7 +77,7 @@ fun DriverDSLExposedInterface.startClient(localServer: ArtemisMessagingServer) =
fun DriverDSLExposedInterface.startClient(remoteNodeInfo: NodeInfo, providedName: String? = null) = fun DriverDSLExposedInterface.startClient(remoteNodeInfo: NodeInfo, providedName: String? = null) =
startClient( startClient(
providedName = providedName ?: "${remoteNodeInfo.identity.name}-client", providedName = providedName ?: "${remoteNodeInfo.legalIdentity.name}-client",
serverAddress = ArtemisMessagingComponent.toHostAndPort(remoteNodeInfo.address) serverAddress = ArtemisMessagingComponent.toHostAndPort(remoteNodeInfo.address)
) )
@ -309,7 +309,7 @@ class DriverDSL(
registerProcess(DriverDSL.startNode(config, quasarJarPath, debugPort)) registerProcess(DriverDSL.startNode(config, quasarJarPath, debugPort))
poll("network map cache for $name") { poll("network map cache for $name") {
networkMapCache.partyNodes.forEach { networkMapCache.partyNodes.forEach {
if (it.identity.name == name) { if (it.legalIdentity.name == name) {
return@poll it return@poll it
} }
} }
@ -383,7 +383,7 @@ class DriverDSL(
networkMapCache.addMapService(networkMapClient, networkMapAddr, true) networkMapCache.addMapService(networkMapClient, networkMapAddr, true)
networkMapNodeInfo = poll("network map cache for $networkMapName") { networkMapNodeInfo = poll("network map cache for $networkMapName") {
networkMapCache.partyNodes.forEach { networkMapCache.partyNodes.forEach {
if (it.identity.name == networkMapName) { if (it.legalIdentity.name == networkMapName) {
return@poll it return@poll it
} }
} }

View File

@ -8,10 +8,7 @@ import com.r3corda.core.RunOnCallerThread
import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.Party
import com.r3corda.core.crypto.X509Utilities import com.r3corda.core.crypto.X509Utilities
import com.r3corda.core.messaging.SingleMessageRecipient import com.r3corda.core.messaging.SingleMessageRecipient
import com.r3corda.core.node.CityDatabase import com.r3corda.core.node.*
import com.r3corda.core.node.CordaPluginRegistry
import com.r3corda.core.node.NodeInfo
import com.r3corda.core.node.PhysicalLocation
import com.r3corda.core.node.services.* import com.r3corda.core.node.services.*
import com.r3corda.core.node.services.NetworkMapCache.MapChangeType import com.r3corda.core.node.services.NetworkMapCache.MapChangeType
import com.r3corda.core.protocols.ProtocolLogic import com.r3corda.core.protocols.ProtocolLogic
@ -96,6 +93,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
val servicesThatAcceptUploads: List<AcceptsFileUpload> = _servicesThatAcceptUploads val servicesThatAcceptUploads: List<AcceptsFileUpload> = _servicesThatAcceptUploads
private val protocolFactories = ConcurrentHashMap<Class<*>, (Party) -> ProtocolLogic<*>>() private val protocolFactories = ConcurrentHashMap<Class<*>, (Party) -> ProtocolLogic<*>>()
protected val partyKeys = mutableSetOf<KeyPair>()
val services = object : ServiceHubInternal() { val services = object : ServiceHubInternal() {
override val networkService: MessagingServiceInternal get() = net 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 identityService: IdentityService get() = identity
override val schedulerService: SchedulerService get() = scheduler override val schedulerService: SchedulerService get() = scheduler
override val clock: Clock = platformClock override val clock: Clock = platformClock
override val myInfo: NodeInfo get() = info
override val schemaService: SchemaService get() = schemas override val schemaService: SchemaService get() = schemas
// Internal only // Internal only
@ -130,7 +129,13 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
} }
val info: NodeInfo by lazy { val info: NodeInfo by lazy {
NodeInfo(net.myAddress, storage.myLegalIdentity, advertisedServices, findMyLocation()) val services = mutableListOf<ServiceEntry>()
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] 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 // TODO: uniquenessProvider creation should be inside makeNotaryService(), but notary service initialisation
// depends on smm, while smm depends on tokenizableServices, which uniquenessProvider is part of // 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() uniquenessProvider = makeUniquenessProvider()
tokenizableServices.add(uniquenessProvider!!) tokenizableServices.add(uniquenessProvider!!)
} }
@ -321,10 +326,10 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
} }
private fun buildAdvertisedServices() { private fun buildAdvertisedServices() {
val serviceTypes = info.advertisedServices.map { it.type } val serviceTypes = info.advertisedServices.map { it.info.type }
if (NetworkMapService.Type in serviceTypes) makeNetworkMapService() if (NetworkMapService.type in serviceTypes) makeNetworkMapService()
val notaryServiceType = serviceTypes.singleOrNull { it.isSubTypeOf(NotaryService.Type) } val notaryServiceType = serviceTypes.singleOrNull { it.isNotary() }
if (notaryServiceType != null) { if (notaryServiceType != null) {
inNodeNotaryService = makeNotaryService(notaryServiceType) inNodeNotaryService = makeNotaryService(notaryServiceType)
} }
@ -335,7 +340,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
* updates) if one has been supplied. * updates) if one has been supplied.
*/ */
private fun registerWithNetworkMap(): ListenableFuture<Unit> { private fun registerWithNetworkMap(): ListenableFuture<Unit> {
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" "Initial network map address must indicate a node that provides a network map service"
} }
services.networkMapCache.addNode(info) services.networkMapCache.addNode(info)
@ -365,11 +370,12 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
val instant = platformClock.instant() val instant = platformClock.instant()
val expires = instant + NetworkMapService.DEFAULT_EXPIRATION_PERIOD val expires = instant + NetworkMapService.DEFAULT_EXPIRATION_PERIOD
val reg = NodeRegistration(info, instant.toEpochMilli(), type, expires) 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) 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() { open protected fun makeNetworkMapService() {
inNodeNetworkMapService = PersistentNetworkMapService(services) inNodeNetworkMapService = PersistentNetworkMapService(services)
@ -379,8 +385,8 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
val timestampChecker = TimestampChecker(platformClock, 30.seconds) val timestampChecker = TimestampChecker(platformClock, 30.seconds)
return when (type) { return when (type) {
SimpleNotaryService.Type -> SimpleNotaryService(services, timestampChecker, uniquenessProvider!!) SimpleNotaryService.type -> SimpleNotaryService(services, timestampChecker, uniquenessProvider!!)
ValidatingNotaryService.Type -> ValidatingNotaryService(services, timestampChecker, uniquenessProvider!!) ValidatingNotaryService.type -> ValidatingNotaryService(services, timestampChecker, uniquenessProvider!!)
else -> { else -> {
throw IllegalArgumentException("Notary type ${type.id} is not handled by makeNotaryService.") 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 { protected open fun makeIdentityService(): IdentityService {
val service = InMemoryIdentityService() 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 -> netMapCache.changed.subscribe { mapChange ->
// TODO how should we handle network map removal
if (mapChange.type == MapChangeType.Added) { 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 checkpointStorage = initialiseCheckpointService(dir)
val transactionStorage = PerFileTransactionStorage(dir.resolve("transactions")) val transactionStorage = PerFileTransactionStorage(dir.resolve("transactions"))
_servicesThatAcceptUploads += attachments _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() val stateMachineTransactionMappingStorage = InMemoryStateMachineRecordedTransactionMappingStorage()
return Pair( return Pair(
constructStorageService(attachments, transactionStorage, stateMachineTransactionMappingStorage, keyPair, identity), constructStorageService(attachments, transactionStorage, stateMachineTransactionMappingStorage),
checkpointStorage checkpointStorage
) )
} }
protected open fun constructStorageService(attachments: NodeAttachmentService, protected open fun constructStorageService(attachments: NodeAttachmentService,
transactionStorage: TransactionStorage, transactionStorage: TransactionStorage,
stateMachineRecordedTransactionMappingStorage: StateMachineRecordedTransactionMappingStorage, stateMachineRecordedTransactionMappingStorage: StateMachineRecordedTransactionMappingStorage) =
keyPair: KeyPair, StorageServiceImpl(attachments, transactionStorage, stateMachineRecordedTransactionMappingStorage)
identity: Party) =
StorageServiceImpl(attachments, transactionStorage, stateMachineRecordedTransactionMappingStorage, keyPair, identity)
private fun obtainKeyPair(dir: Path): Pair<Party, KeyPair> { 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<Party, KeyPair> {
// Load the private identity key, creating it if necessary. The identity key is a long term well known key that // 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 // 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 // "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 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. // the legal name is actually validated in some way.
val privKeyFile = dir.resolve(PRIVATE_KEY_FILE_NAME) val privKeyFile = dir.resolve(privateKeyFileName)
val pubIdentityFile = dir.resolve(PUBLIC_IDENTITY_FILE_NAME) 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!") log.info("Identity key not found, generating fresh key!")
val keyPair: KeyPair = generateKeyPair() val keyPair: KeyPair = generateKeyPair()
keyPair.serialize().writeToFile(privKeyFile) 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 // We include the Party class with the file here to help catch mixups when admins provide files of the
// wrong type by mistake. // wrong type by mistake.
myIdentity.serialize().writeToFile(pubIdentityFile) 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 // This is just a sanity check. It shouldn't fail unless the admin has fiddled with the files and messed
// things up for us. // things up for us.
val myIdentity = Files.readAllBytes(pubIdentityFile).deserialize<Party>() val myIdentity = Files.readAllBytes(pubIdentityFile).deserialize<Party>()
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:" + 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. // Load the private key.
val keyPair = Files.readAllBytes(privKeyFile).deserialize<KeyPair>() val keyPair = Files.readAllBytes(privKeyFile).deserialize<KeyPair>()
Pair(myIdentity, keyPair) Pair(myIdentity, keyPair)
} }
partyKeys += identityAndKey.second
return identityAndKey
} }
protected open fun generateKeyPair() = com.r3corda.core.crypto.generateKeyPair() protected open fun generateKeyPair() = com.r3corda.core.crypto.generateKeyPair()

View File

@ -117,7 +117,8 @@ class Node(override val configuration: FullNodeConfiguration, networkMapAddress:
artemisAddress 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, return NodeMessagingClient(configuration, serverAddr, myIdentityOrNullIfNetworkMapService, serverThread,
persistenceTx = { body: () -> Unit -> databaseTransaction(database) { body() } }) persistenceTx = { body: () -> Unit -> databaseTransaction(database) { body() } })
} }

View File

@ -8,7 +8,6 @@ import com.r3corda.core.crypto.toStringShort
import com.r3corda.core.node.ServiceHub import com.r3corda.core.node.ServiceHub
import com.r3corda.core.node.services.Vault import com.r3corda.core.node.services.Vault
import com.r3corda.core.transactions.TransactionBuilder 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.CordaRPCOps
import com.r3corda.node.services.messaging.StateMachineInfo import com.r3corda.node.services.messaging.StateMachineInfo
import com.r3corda.node.services.messaging.StateMachineUpdate import com.r3corda.node.services.messaging.StateMachineUpdate
@ -93,10 +92,11 @@ class ServerRPCOps(
private fun exitCash(req: ClientToServiceCommand.ExitCash): TransactionBuildResult { private fun exitCash(req: ClientToServiceCommand.ExitCash): TransactionBuildResult {
val builder: TransactionBuilder = TransactionType.General.Builder(null) val builder: TransactionBuilder = TransactionType.General.Builder(null)
try { try {
val issuer = PartyAndReference(services.storageService.myLegalIdentity, req.issueRef) val issuer = PartyAndReference(services.myInfo.legalIdentity, req.issueRef)
Cash().generateExit(builder, req.amount.issuedBy(issuer), Cash().generateExit(builder, req.amount.issuedBy(issuer),
services.vaultService.currentVault.statesOfType<Cash.State>().filter { it.state.data.owner == issuer.party.owningKey }) services.vaultService.currentVault.statesOfType<Cash.State>().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 // Work out who the owners of the burnt states were
val inputStatesNullable = services.vaultService.statesForRefs(builder.inputStates()) 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 // TODO: Make a lightweight protocol that manages this workflow, rather than embedding it directly in the service
private fun issueCash(req: ClientToServiceCommand.IssueCash): TransactionBuildResult { private fun issueCash(req: ClientToServiceCommand.IssueCash): TransactionBuildResult {
val builder: TransactionBuilder = TransactionType.General.Builder(notary = null) 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) 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) val tx = builder.toSignedTransaction(checkSufficientSignatures = true)
// Issuance transactions do not need to be notarised, so we can skip directly to broadcasting it // 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)) val protocol = BroadcastTransactionProtocol(tx, setOf(req), setOf(req.recipient))

View File

@ -6,6 +6,7 @@ import com.r3corda.core.node.services.ServiceType
* Placeholder interface for regulator services. * Placeholder interface for regulator services.
*/ */
interface RegulatorService { interface RegulatorService {
object Type : ServiceType("corda.regulator") companion object {
val type = ServiceType.regulator
}
} }

View File

@ -54,7 +54,7 @@ class FullNodeConfiguration(config: Config) : NodeConfiguration {
advertisedServices.add(ServiceInfo.parse(serviceId)) 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!!) val networkMapMessageAddress: SingleMessageRecipient? = if (networkMapAddress == null) null else NodeMessagingClient.makeNetworkMapAddress(networkMapAddress!!)
return Node(this, networkMapMessageAddress, advertisedServices) return Node(this, networkMapMessageAddress, advertisedServices)
} }

View File

@ -41,11 +41,11 @@ import javax.annotation.concurrent.ThreadSafe
@ThreadSafe @ThreadSafe
open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCache { open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCache {
override val networkMapNodes: List<NodeInfo> override val networkMapNodes: List<NodeInfo>
get() = get(NetworkMapService.Type) get() = get(NetworkMapService.type)
override val regulators: List<NodeInfo> override val regulators: List<NodeInfo>
get() = get(RegulatorService.Type) get() = get(ServiceType.regulator)
override val notaryNodes: List<NodeInfo> override val notaryNodes: List<NodeInfo>
get() = get(NotaryService.Type) get() = get(ServiceType.notary)
override val partyNodes: List<NodeInfo> override val partyNodes: List<NodeInfo>
get() = registeredNodes.map { it.value } get() = registeredNodes.map { it.value }
private val _changed = PublishSubject.create<MapChange>() private val _changed = PublishSubject.create<MapChange>()
@ -58,10 +58,13 @@ open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCach
protected var registeredNodes = Collections.synchronizedMap(HashMap<Party, NodeInfo>()) protected var registeredNodes = Collections.synchronizedMap(HashMap<Party, NodeInfo>())
override fun get() = registeredNodes.map { it.value } 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 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 getNodeByLegalName(name: String) = get().singleOrNull { it.legalIdentity.name == name }
override fun getNodeByPublicKey(publicKey: PublicKey) = get().singleOrNull { it.identity.owningKey == publicKey } 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, override fun addMapService(net: MessagingService, networkMapAddress: SingleMessageRecipient, subscribe: Boolean,
ifChangedSinceVer: Int?): ListenableFuture<Unit> { ifChangedSinceVer: Int?): ListenableFuture<Unit> {
@ -96,7 +99,7 @@ open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCach
} }
override fun addNode(node: NodeInfo) { override fun addNode(node: NodeInfo) {
val oldValue = registeredNodes.put(node.identity, node) val oldValue = registeredNodes.put(node.legalIdentity, node)
if (oldValue == null) { if (oldValue == null) {
_changed.onNext(MapChange(node, oldValue, MapChangeType.Added)) _changed.onNext(MapChange(node, oldValue, MapChangeType.Added))
} else if(oldValue != node) { } else if(oldValue != node) {
@ -105,7 +108,7 @@ open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCach
} }
override fun removeNode(node: NodeInfo) { override fun removeNode(node: NodeInfo) {
val oldValue = registeredNodes.remove(node.identity) val oldValue = registeredNodes.remove(node.legalIdentity)
_changed.onNext(MapChange(node, oldValue, MapChangeType.Removed)) _changed.onNext(MapChange(node, oldValue, MapChangeType.Removed))
} }

View File

@ -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 // a concept of identity changes over time, should that include the node for an identity? If so, that is likely to
// replace this service. // replace this service.
interface NetworkMapService { interface NetworkMapService {
object Type : ServiceType("corda.network_map")
companion object { companion object {
val DEFAULT_EXPIRATION_PERIOD = Period.ofWeeks(4) val DEFAULT_EXPIRATION_PERIOD = Period.ofWeeks(4)
@ -63,6 +62,8 @@ interface NetworkMapService {
val PUSH_ACK_PROTOCOL_TOPIC = "platform.network_map.push_ack" val PUSH_ACK_PROTOCOL_TOPIC = "platform.network_map.push_ack"
val logger = loggerFor<NetworkMapService>() val logger = loggerFor<NetworkMapService>()
val type = ServiceType.corda.getSubType("network_map")
} }
val nodes: List<NodeInfo> val nodes: List<NodeInfo>
@ -270,7 +271,7 @@ abstract class AbstractNetworkMapService
// Update the current value atomically, so that if multiple updates come // 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 // in on different threads, there is no risk of a race condition while checking
// sequence numbers. // 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 changed = existing == null || existing.reg.serial < change.serial
if (changed) { if (changed) {
when (change.type) { when (change.type) {
@ -332,7 +333,7 @@ class NodeRegistration(val node: NodeInfo, val serial: Long, val type: AddOrRemo
*/ */
fun toWire(privateKey: PrivateKey): WireNodeRegistration { fun toWire(privateKey: PrivateKey): WireNodeRegistration {
val regSerialized = this.serialize() 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) return WireNodeRegistration(regSerialized, regSig)
} }
@ -346,7 +347,7 @@ class NodeRegistration(val node: NodeInfo, val serial: Long, val type: AddOrRemo
class WireNodeRegistration(raw: SerializedBytes<NodeRegistration>, sig: DigitalSignature.WithKey) : SignedData<NodeRegistration>(raw, sig) { class WireNodeRegistration(raw: SerializedBytes<NodeRegistration>, sig: DigitalSignature.WithKey) : SignedData<NodeRegistration>(raw, sig) {
@Throws(IllegalArgumentException::class) @Throws(IllegalArgumentException::class)
override fun verifyData(data: NodeRegistration) { override fun verifyData(data: NodeRegistration) {
require(data.node.identity.owningKey == sig.by) require(data.node.legalIdentity.owningKey == sig.by)
} }
} }

View File

@ -1,16 +1,12 @@
package com.r3corda.node.services.persistence 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.AttachmentStorage
import com.r3corda.core.node.services.StateMachineRecordedTransactionMappingStorage import com.r3corda.core.node.services.StateMachineRecordedTransactionMappingStorage
import com.r3corda.core.node.services.TransactionStorage import com.r3corda.core.node.services.TransactionStorage
import com.r3corda.core.node.services.TxWritableStorageService import com.r3corda.core.node.services.TxWritableStorageService
import com.r3corda.core.serialization.SingletonSerializeAsToken import com.r3corda.core.serialization.SingletonSerializeAsToken
import java.security.KeyPair
open class StorageServiceImpl(override val attachments: AttachmentStorage, open class StorageServiceImpl(override val attachments: AttachmentStorage,
override val validatedTransactions: TransactionStorage, override val validatedTransactions: TransactionStorage,
override val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage, override val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage)
override val myLegalIdentityKey: KeyPair,
override val myLegalIdentity: Party = Party("Unit test party", myLegalIdentityKey.public))
: SingletonSerializeAsToken(), TxWritableStorageService : SingletonSerializeAsToken(), TxWritableStorageService

View File

@ -187,7 +187,7 @@ class ProtocolStateMachineImpl<R>(override val id: StateMachineRunId,
val session = ProtocolSession(sessionProtocol, otherParty, random63BitValue(), null) val session = ProtocolSession(sessionProtocol, otherParty, random63BitValue(), null)
openSessions[Pair(sessionProtocol, otherParty)] = session openSessions[Pair(sessionProtocol, otherParty)] = session
val counterpartyProtocol = sessionProtocol.getCounterpartyMarker(otherParty).name 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) val sessionInitResponse = sendAndReceiveInternal(session, sessionInit, SessionInitResponse::class.java)
if (sessionInitResponse is SessionConfirm) { if (sessionInitResponse is SessionConfirm) {
session.otherPartySessionId = sessionInitResponse.initiatedSessionId session.otherPartySessionId = sessionInitResponse.initiatedSessionId

View File

@ -386,7 +386,7 @@ class StateMachineManager(val serviceHub: ServiceHubInternal,
} }
private fun sendSessionMessage(party: Party, message: SessionMessage, psm: ProtocolStateMachineImpl<*>?) { 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") ?: throw IllegalArgumentException("Don't know about party $party")
val logger = psm?.logger ?: logger val logger = psm?.logger ?: logger
logger.trace { "${psm?.id} sending $message to party $party" } logger.trace { "${psm?.id} sending $message to party $party" }

View File

@ -5,6 +5,7 @@ import com.r3corda.core.node.services.ServiceType
import com.r3corda.core.serialization.SingletonSerializeAsToken import com.r3corda.core.serialization.SingletonSerializeAsToken
import com.r3corda.node.services.api.ServiceHubInternal import com.r3corda.node.services.api.ServiceHubInternal
import com.r3corda.protocols.NotaryProtocol import com.r3corda.protocols.NotaryProtocol
import kotlin.reflect.KClass
/** /**
* A Notary service acts as the final signer of a transaction ensuring two things: * 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. * This is the base implementation that can be customised with specific Notary transaction commit protocol.
*/ */
abstract class NotaryService(services: ServiceHubInternal) : SingletonSerializeAsToken() { 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 { init {
services.registerProtocolInitiator(NotaryProtocol.Client::class) { createProtocol(it) } services.registerProtocolInitiator(NotaryProtocol.Client::class) { createProtocol(it) }

View File

@ -12,7 +12,9 @@ import com.r3corda.protocols.NotaryProtocol
class SimpleNotaryService(services: ServiceHubInternal, class SimpleNotaryService(services: ServiceHubInternal,
val timestampChecker: TimestampChecker, val timestampChecker: TimestampChecker,
val uniquenessProvider: UniquenessProvider) : NotaryService(services) { 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 { override fun createProtocol(otherParty: Party): NotaryProtocol.Service {
return NotaryProtocol.Service(otherParty, timestampChecker, uniquenessProvider) return NotaryProtocol.Service(otherParty, timestampChecker, uniquenessProvider)

View File

@ -11,7 +11,9 @@ import com.r3corda.protocols.ValidatingNotaryProtocol
class ValidatingNotaryService(services: ServiceHubInternal, class ValidatingNotaryService(services: ServiceHubInternal,
val timestampChecker: TimestampChecker, val timestampChecker: TimestampChecker,
val uniquenessProvider: UniquenessProvider) : NotaryService(services) { 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 { override fun createProtocol(otherParty: Party): ValidatingNotaryProtocol {
return ValidatingNotaryProtocol(otherParty, timestampChecker, uniquenessProvider) return ValidatingNotaryProtocol(otherParty, timestampChecker, uniquenessProvider)

View File

@ -38,9 +38,9 @@ class ServerRPCTest {
@Before @Before
fun setup() { fun setup() {
network = MockNetwork() 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) 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) rpc = ServerRPCOps(aliceNode.services, aliceNode.smm, aliceNode.database)
stateMachineUpdates = rpc.stateMachinesAndUpdates().second stateMachineUpdates = rpc.stateMachinesAndUpdates().second
@ -57,13 +57,13 @@ class ServerRPCTest {
assertFalse(aliceNode.services.vaultService.currentVault.states.iterator().hasNext()) assertFalse(aliceNode.services.vaultService.currentVault.states.iterator().hasNext())
// Tell the monitoring service node to issue some cash // Tell the monitoring service node to issue some cash
val recipient = aliceNode.services.storageService.myLegalIdentity val recipient = aliceNode.info.legalIdentity
val outEvent = ClientToServiceCommand.IssueCash(Amount(quantity, GBP), ref, recipient, DUMMY_NOTARY) val outEvent = ClientToServiceCommand.IssueCash(Amount(quantity, GBP), ref, recipient, notaryNode.info.notaryIdentity)
rpc.executeCommand(outEvent) rpc.executeCommand(outEvent)
network.runNetwork() network.runNetwork()
val expectedState = Cash.State(Amount(quantity, val expectedState = Cash.State(Amount(quantity,
Issued(aliceNode.services.storageService.myLegalIdentity.ref(ref), GBP)), Issued(aliceNode.info.legalIdentity.ref(ref), GBP)),
recipient.owningKey) recipient.owningKey)
var issueSmId: StateMachineRunId? = null var issueSmId: StateMachineRunId? = null
@ -99,15 +99,15 @@ class ServerRPCTest {
rpc.executeCommand(ClientToServiceCommand.IssueCash( rpc.executeCommand(ClientToServiceCommand.IssueCash(
amount = Amount(100, USD), amount = Amount(100, USD),
issueRef = OpaqueBytes(ByteArray(1, { 1 })), issueRef = OpaqueBytes(ByteArray(1, { 1 })),
recipient = aliceNode.services.storageService.myLegalIdentity, recipient = aliceNode.info.legalIdentity,
notary = notaryNode.services.storageService.myLegalIdentity notary = notaryNode.info.notaryIdentity
)) ))
network.runNetwork() network.runNetwork()
rpc.executeCommand(ClientToServiceCommand.PayCash( rpc.executeCommand(ClientToServiceCommand.PayCash(
amount = Amount(100, Issued(PartyAndReference(aliceNode.services.storageService.myLegalIdentity, OpaqueBytes(ByteArray(1, { 1 }))), USD)), amount = Amount(100, Issued(PartyAndReference(aliceNode.info.legalIdentity, OpaqueBytes(ByteArray(1, { 1 }))), USD)),
recipient = aliceNode.services.storageService.myLegalIdentity recipient = aliceNode.info.legalIdentity
)) ))
network.runNetwork() network.runNetwork()
@ -142,7 +142,7 @@ class ServerRPCTest {
val signaturePubKeys = tx.sigs.map { it.by }.toSet() val signaturePubKeys = tx.sigs.map { it.by }.toSet()
// Only Alice signed // Only Alice signed
require(signaturePubKeys.size == 1) require(signaturePubKeys.size == 1)
require(signaturePubKeys.contains(aliceNode.services.storageService.myLegalIdentity.owningKey)) require(signaturePubKeys.contains(aliceNode.info.legalIdentity.owningKey))
}, },
// MOVE // MOVE
expect { tx -> expect { tx ->
@ -151,8 +151,8 @@ class ServerRPCTest {
val signaturePubKeys = tx.sigs.map { it.by }.toSet() val signaturePubKeys = tx.sigs.map { it.by }.toSet()
// Alice and Notary signed // Alice and Notary signed
require(signaturePubKeys.size == 2) require(signaturePubKeys.size == 2)
require(signaturePubKeys.contains(aliceNode.services.storageService.myLegalIdentity.owningKey)) require(signaturePubKeys.contains(aliceNode.info.legalIdentity.owningKey))
require(signaturePubKeys.contains(notaryNode.services.storageService.myLegalIdentity.owningKey)) require(signaturePubKeys.contains(notaryNode.info.notaryIdentity.owningKey))
} }
) )
} }

View File

@ -54,7 +54,7 @@ class AttachmentTests {
// Get node one to run a protocol to fetch it and insert it. // Get node one to run a protocol to fetch it and insert it.
network.runNetwork() 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() network.runNetwork()
assertEquals(0, f1.get().fromDisk.size) 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. // Shut down node zero and ensure node one can still resolve the attachment.
n0.stop() n0.stop()
val response: FetchDataProtocol.Result<Attachment> = n1.services.startProtocol("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.identity)).get() val response: FetchDataProtocol.Result<Attachment> = n1.services.startProtocol("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.legalIdentity)).get()
assertEquals(attachment, response.fromDisk[0]) assertEquals(attachment, response.fromDisk[0])
} }
@ -76,7 +76,7 @@ class AttachmentTests {
// Get node one to fetch a non-existent attachment. // Get node one to fetch a non-existent attachment.
val hash = SecureHash.randomSHA256() val hash = SecureHash.randomSHA256()
network.runNetwork() 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() network.runNetwork()
val e = assertFailsWith<FetchDataProtocol.HashNotFound> { rootCauseExceptions { f1.get() } } val e = assertFailsWith<FetchDataProtocol.HashNotFound> { rootCauseExceptions { f1.get() } }
assertEquals(hash, e.requested) 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) val n1 = network.createNode(n0.info.address)
// Insert an attachment into node zero's store directly. // 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. // Get n1 to fetch the attachment. Should receive corrupted bytes.
network.runNetwork() 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() network.runNetwork()
assertFailsWith<FetchDataProtocol.DownloadedVsRequestedDataMismatch> { assertFailsWith<FetchDataProtocol.DownloadedVsRequestedDataMismatch> {
rootCauseExceptions { f1.get() } rootCauseExceptions { f1.get() }

View File

@ -41,7 +41,7 @@ class InMemoryMessagingTests {
@Test @Test
fun basics() { 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 node2 = network.createNode(networkMapAddress = node1.info.address)
val node3 = network.createNode(networkMapAddress = node1.info.address) val node3 = network.createNode(networkMapAddress = node1.info.address)
@ -70,7 +70,7 @@ class InMemoryMessagingTests {
@Test @Test
fun broadcast() { 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 node2 = network.createNode(networkMapAddress = node1.info.address)
val node3 = network.createNode(networkMapAddress = node1.info.address) val node3 = network.createNode(networkMapAddress = node1.info.address)
@ -89,7 +89,7 @@ class InMemoryMessagingTests {
*/ */
@Test @Test
fun `skip unhandled messages`() { 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) val node2 = network.createNode(networkMapAddress = node1.info.address)
var received: Int = 0 var received: Int = 0

View File

@ -8,11 +8,11 @@ import com.r3corda.core.crypto.Party
import com.r3corda.core.crypto.SecureHash import com.r3corda.core.crypto.SecureHash
import com.r3corda.core.days import com.r3corda.core.days
import com.r3corda.core.messaging.SingleMessageRecipient import com.r3corda.core.messaging.SingleMessageRecipient
import com.r3corda.core.node.ServiceHub
import com.r3corda.core.node.services.* import com.r3corda.core.node.services.*
import com.r3corda.core.protocols.ProtocolStateMachine import com.r3corda.core.protocols.ProtocolStateMachine
import com.r3corda.core.protocols.StateMachineRunId import com.r3corda.core.protocols.StateMachineRunId
import com.r3corda.core.transactions.SignedTransaction import com.r3corda.core.transactions.SignedTransaction
import com.r3corda.core.transactions.TransactionBuilder
import com.r3corda.core.transactions.WireTransaction import com.r3corda.core.transactions.WireTransaction
import com.r3corda.core.utilities.DUMMY_NOTARY import com.r3corda.core.utilities.DUMMY_NOTARY
import com.r3corda.core.utilities.DUMMY_NOTARY_KEY import com.r3corda.core.utilities.DUMMY_NOTARY_KEY
@ -85,16 +85,20 @@ class TwoPartyTradeProtocolTests {
notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name, ALICE_KEY) aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name, ALICE_KEY)
bobNode = net.createPartyNode(notaryNode.info.address, BOB.name, BOB_KEY) bobNode = net.createPartyNode(notaryNode.info.address, BOB.name, BOB_KEY)
val aliceKey = aliceNode.services.legalIdentityKey
val notaryKey = notaryNode.services.notaryIdentityKey
aliceNode.disableDBCloseOnStop() aliceNode.disableDBCloseOnStop()
bobNode.disableDBCloseOnStop() bobNode.disableDBCloseOnStop()
databaseTransaction(bobNode.database) { 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, val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null).second 1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null, notaryNode.info.notaryIdentity).second
insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey, notaryNode.storage.myLegalIdentityKey)
insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey, notaryKey)
val (bobPsm, aliceResult) = runBuyerAndSeller("alice's paper".outputStateAndRef()) val (bobPsm, aliceResult) = runBuyerAndSeller("alice's paper".outputStateAndRef())
// TODO: Verify that the result was inserted into the transaction database. // 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) notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name, ALICE_KEY) aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name, ALICE_KEY)
bobNode = net.createPartyNode(notaryNode.info.address, BOB.name, BOB_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 bobAddr = bobNode.net.myAddress as InMemoryMessagingNetwork.Handle
val networkMapAddr = notaryNode.info.address val networkMapAddr = notaryNode.info.address
@ -128,11 +134,11 @@ class TwoPartyTradeProtocolTests {
net.runNetwork() // Clear network map registration messages net.runNetwork() // Clear network map registration messages
databaseTransaction(bobNode.database) { 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, val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null).second 1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null, notaryNode.info.notaryIdentity).second
insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey) insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey, notaryKey)
val aliceFuture = runBuyerAndSeller("alice's paper".outputStateAndRef()).sellerResult 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. // 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( override fun constructStorageService(
attachments: NodeAttachmentService, attachments: NodeAttachmentService,
transactionStorage: TransactionStorage, transactionStorage: TransactionStorage,
stateMachineRecordedTransactionMappingStorage: StateMachineRecordedTransactionMappingStorage, stateMachineRecordedTransactionMappingStorage: StateMachineRecordedTransactionMappingStorage
keyPair: KeyPair,
identity: Party
): StorageServiceImpl { ): 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) notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
aliceNode = makeNodeWithTracking(notaryNode.info.address, ALICE.name, ALICE_KEY) aliceNode = makeNodeWithTracking(notaryNode.info.address, ALICE.name, ALICE_KEY)
bobNode = makeNodeWithTracking(notaryNode.info.address, BOB.name, BOB_KEY) bobNode = makeNodeWithTracking(notaryNode.info.address, BOB.name, BOB_KEY)
val aliceKey = aliceNode.services.legalIdentityKey
ledger(aliceNode.services) { ledger(aliceNode.services) {
@ -228,11 +233,11 @@ class TwoPartyTradeProtocolTests {
} }
val attachmentID = attachment(ByteArrayInputStream(stream.toByteArray())) 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 bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode)
val alicesFakePaper = fillUpForSeller(false, aliceNode.storage.myLegalIdentity.owningKey, val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID).second 1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID, notaryNode.info.notaryIdentity).second
val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey) val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey)
net.runNetwork() // Clear network map registration messages net.runNetwork() // Clear network map registration messages
@ -307,6 +312,7 @@ class TwoPartyTradeProtocolTests {
notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
aliceNode = makeNodeWithTracking(notaryNode.info.address, ALICE.name, ALICE_KEY) aliceNode = makeNodeWithTracking(notaryNode.info.address, ALICE.name, ALICE_KEY)
bobNode = makeNodeWithTracking(notaryNode.info.address, BOB.name, BOB_KEY) bobNode = makeNodeWithTracking(notaryNode.info.address, BOB.name, BOB_KEY)
val aliceKey = aliceNode.services.legalIdentityKey
ledger(aliceNode.services) { ledger(aliceNode.services) {
@ -319,11 +325,11 @@ class TwoPartyTradeProtocolTests {
} }
val attachmentID = attachment(ByteArrayInputStream(stream.toByteArray())) 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) insertFakeTransactions(bobsFakeCash, bobNode)
val alicesFakePaper = fillUpForSeller(false, aliceNode.storage.myLegalIdentity.owningKey, val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID).second 1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID, notaryNode.info.notaryIdentity).second
insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey) insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey)
net.runNetwork() // Clear network map registration messages net.runNetwork() // Clear network map registration messages
@ -387,9 +393,9 @@ class TwoPartyTradeProtocolTests {
private fun runBuyerAndSeller(assetToSell: StateAndRef<OwnableState>) : RunResult { private fun runBuyerAndSeller(assetToSell: StateAndRef<OwnableState>) : RunResult {
val buyerFuture = bobNode.initiateSingleShotProtocol(Seller::class) { otherParty -> 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 val sellerResultFuture = aliceNode.smm.add("seller", seller).resultFuture
return RunResult(buyerFuture, sellerResultFuture, seller.psm.id) return RunResult(buyerFuture, sellerResultFuture, seller.psm.id)
} }
@ -402,15 +408,16 @@ class TwoPartyTradeProtocolTests {
notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name, ALICE_KEY) aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name, ALICE_KEY)
bobNode = net.createPartyNode(notaryNode.info.address, BOB.name, BOB_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 issuer = MEGA_CORP.ref(1, 2, 3)
val bobKey = bobNode.keyManagement.freshKey() val bobsBadCash = fillUpForBuyer(bobError, bobKey.public, notaryNode.info.notaryIdentity).second
val bobsBadCash = fillUpForBuyer(bobError, bobKey.public).second val alicesFakePaper = fillUpForSeller(aliceError, aliceNode.info.legalIdentity.owningKey,
val alicesFakePaper = fillUpForSeller(aliceError, aliceNode.storage.myLegalIdentity.owningKey, 1200.DOLLARS `issued by` issuer, null, notaryNode.info.notaryIdentity).second
1200.DOLLARS `issued by` issuer, null).second
insertFakeTransactions(bobsBadCash, bobNode, bobNode.storage.myLegalIdentityKey, bobNode.storage.myLegalIdentityKey) insertFakeTransactions(bobsBadCash, bobNode, bobKey)
insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey) insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey)
net.runNetwork() // Clear network map registration messages net.runNetwork() // Clear network map registration messages
@ -452,14 +459,15 @@ class TwoPartyTradeProtocolTests {
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForBuyer( private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForBuyer(
withError: Boolean, withError: Boolean,
owner: PublicKey = BOB_PUBKEY): Pair<Vault, List<WireTransaction>> { owner: PublicKey = BOB_PUBKEY,
notary: Party): Pair<Vault, List<WireTransaction>> {
val issuer = DUMMY_CASH_ISSUER val issuer = DUMMY_CASH_ISSUER
// Bob (Buyer) has some cash he got from the Bank of Elbonia, Alice (Seller) has some commercial paper she // Bob (Buyer) has some cash he got from the Bank of Elbonia, Alice (Seller) has some commercial paper she
// wants to sell to Bob. // wants to sell to Bob.
val eb1 = transaction { val eb1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
// Issued money to itself. // Issued money to itself.
output("elbonian money 1") { 800.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") { 1000.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) if (!withError)
command(DUMMY_CASH_ISSUER_KEY.public) { Cash.Commands.Issue() } command(DUMMY_CASH_ISSUER_KEY.public) { Cash.Commands.Issue() }
else else
@ -474,17 +482,17 @@ class TwoPartyTradeProtocolTests {
} }
// Bob gets some cash onto the ledger from BoE // Bob gets some cash onto the ledger from BoE
val bc1 = transaction { val bc1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
input("elbonian money 1") 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() } command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
this.verifies() this.verifies()
} }
val bc2 = transaction { val bc2 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
input("elbonian money 2") input("elbonian money 2")
output("bob cash 2") { 300.DOLLARS.CASH `issued by` issuer `owned by` owner } output("bob cash 2", notary = notary) { 300.DOLLARS.CASH `issued by` issuer `owned by` owner }
output { 700.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } // Change output. output(notary = notary) { 700.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } // Change output.
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() } command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
this.verifies() this.verifies()
} }
@ -497,9 +505,10 @@ class TwoPartyTradeProtocolTests {
withError: Boolean, withError: Boolean,
owner: PublicKey, owner: PublicKey,
amount: Amount<Issued<Currency>>, amount: Amount<Issued<Currency>>,
attachmentID: SecureHash?): Pair<Vault, List<WireTransaction>> { attachmentID: SecureHash?,
val ap = transaction { notary: Party): Pair<Vault, List<WireTransaction>> {
output("alice's paper") { 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) CommercialPaper.State(MEGA_CORP.ref(1, 2, 3), owner, amount, TEST_TX_TIME + 7.days)
} }
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() } command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }

View File

@ -41,19 +41,19 @@ abstract class AbstractNetworkMapServiceTest {
// Confirm the service contains no nodes as own node only registered if network is run. // Confirm the service contains no nodes as own node only registered if network is run.
assertEquals(0, service().nodes.count()) 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 // Register the new node
val instant = Instant.now() val instant = Instant.now()
val expires = instant + NetworkMapService.DEFAULT_EXPIRATION_PERIOD 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 addChange = NodeRegistration(registerNode.info, instant.toEpochMilli(), AddOrRemove.ADD, expires)
val addWireChange = addChange.toWire(nodeKey.private) val addWireChange = addChange.toWire(nodeKey.private)
service().processRegistrationChangeRequest(RegistrationRequest(addWireChange, mapServiceNode.info.address, Long.MIN_VALUE)) service().processRegistrationChangeRequest(RegistrationRequest(addWireChange, mapServiceNode.info.address, Long.MIN_VALUE))
swizzle() swizzle()
assertEquals(1, service().nodes.count()) 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 // Re-registering should be a no-op
service().processRegistrationChangeRequest(RegistrationRequest(addWireChange, mapServiceNode.info.address, Long.MIN_VALUE)) 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) assert(service().processRegistrationChangeRequest(RegistrationRequest(removeWireChange, mapServiceNode.info.address, Long.MIN_VALUE)).success)
swizzle() 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() swizzle()
// Trying to de-register a node that doesn't exist should fail // Trying to de-register a node that doesn't exist should fail
@ -88,7 +88,7 @@ abstract class AbstractNetworkMapServiceTest {
assertEquals(2, fetchPsm.get()?.count()) assertEquals(2, fetchPsm.get()?.count())
// Forcibly deregister the second node // Forcibly deregister the second node
val nodeKey = registerNode.storage.myLegalIdentityKey val nodeKey = registerNode.services.legalIdentityKey
val instant = Instant.now() val instant = Instant.now()
val expires = instant + NetworkMapService.DEFAULT_EXPIRATION_PERIOD val expires = instant + NetworkMapService.DEFAULT_EXPIRATION_PERIOD
val reg = NodeRegistration(registerNode.info, instant.toEpochMilli()+1, AddOrRemove.REMOVE, expires) 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)) assertEquals(0, service().getUnacknowledgedCount(registerNode.info.address, startingMapVersion))
// Fire off an update // Fire off an update
val nodeKey = registerNode.storage.myLegalIdentityKey val nodeKey = registerNode.services.legalIdentityKey
var seq = 0L var seq = 0L
val expires = Instant.now() + NetworkMapService.DEFAULT_EXPIRATION_PERIOD val expires = Instant.now() + NetworkMapService.DEFAULT_EXPIRATION_PERIOD
var reg = NodeRegistration(registerNode.info, seq++, AddOrRemove.ADD, expires) var reg = NodeRegistration(registerNode.info, seq++, AddOrRemove.ADD, expires)

View File

@ -3,6 +3,7 @@ package com.r3corda.node.services
import com.codahale.metrics.MetricRegistry import com.codahale.metrics.MetricRegistry
import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.ListenableFuture
import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.Party
import com.r3corda.core.node.NodeInfo
import com.r3corda.core.node.services.* import com.r3corda.core.node.services.*
import com.r3corda.core.protocols.ProtocolLogic import com.r3corda.core.protocols.ProtocolLogic
import com.r3corda.core.protocols.ProtocolLogicRefFactory import com.r3corda.core.protocols.ProtocolLogicRefFactory
@ -51,6 +52,8 @@ open class MockServiceHubInternal(
get() = scheduler ?: throw UnsupportedOperationException() get() = scheduler ?: throw UnsupportedOperationException()
override val clock: Clock override val clock: Clock
get() = overrideClock ?: throw UnsupportedOperationException() get() = overrideClock ?: throw UnsupportedOperationException()
override val myInfo: NodeInfo
get() = throw UnsupportedOperationException()
override val monitoringService: MonitoringService = MonitoringService(MetricRegistry()) override val monitoringService: MonitoringService = MonitoringService(MetricRegistry())
override val protocolLogicRefFactory: ProtocolLogicRefFactory override val protocolLogicRefFactory: ProtocolLogicRefFactory

View File

@ -259,7 +259,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
private fun scheduleTX(instant: Instant, increment: Int = 1): ScheduledStateRef? { private fun scheduleTX(instant: Instant, increment: Int = 1): ScheduledStateRef? {
var scheduledRef: ScheduledStateRef? = null var scheduledRef: ScheduledStateRef? = null
apply { apply {
val freshKey = services.storageService.myLegalIdentityKey val freshKey = services.keyManagementService.freshKey()
val state = TestState(factory.create(TestProtocolLogic::class.java, increment), instant) val state = TestState(factory.create(TestProtocolLogic::class.java, increment), instant)
val usefulTX = TransactionType.General.Builder(null).apply { val usefulTX = TransactionType.General.Builder(null).apply {
addOutputState(state, DUMMY_NOTARY) addOutputState(state, DUMMY_NOTARY)

View File

@ -36,18 +36,18 @@ class NotaryChangeTests {
oldNotaryNode = net.createNode( oldNotaryNode = net.createNode(
legalName = DUMMY_NOTARY.name, legalName = DUMMY_NOTARY.name,
keyPair = DUMMY_NOTARY_KEY, 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) clientNodeA = net.createNode(networkMapAddress = oldNotaryNode.info.address)
clientNodeB = 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 net.runNetwork() // Clear network map registration messages
} }
@Test @Test
fun `should change notary for a state with single participant`() { fun `should change notary for a state with single participant`() {
val state = issueState(clientNodeA) val state = issueState(clientNodeA, oldNotaryNode)
val newNotary = newNotaryNode.info.identity val newNotary = newNotaryNode.info.notaryIdentity
val protocol = Instigator(state, newNotary) val protocol = Instigator(state, newNotary)
val future = clientNodeA.services.startProtocol("notary-change", protocol) val future = clientNodeA.services.startProtocol("notary-change", protocol)
@ -59,8 +59,8 @@ class NotaryChangeTests {
@Test @Test
fun `should change notary for a state with multiple participants`() { fun `should change notary for a state with multiple participants`() {
val state = issueMultiPartyState(clientNodeA, clientNodeB) val state = issueMultiPartyState(clientNodeA, clientNodeB, oldNotaryNode)
val newNotary = newNotaryNode.info.identity val newNotary = newNotaryNode.info.notaryIdentity
val protocol = Instigator(state, newNotary) val protocol = Instigator(state, newNotary)
val future = clientNodeA.services.startProtocol("notary-change", protocol) val future = clientNodeA.services.startProtocol("notary-change", protocol)
@ -75,7 +75,7 @@ class NotaryChangeTests {
@Test @Test
fun `should throw when a participant refuses to change Notary`() { 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 newEvilNotary = Party("Evil Notary", generateKeyPair().public)
val protocol = Instigator(state, newEvilNotary) val protocol = Instigator(state, newEvilNotary)
val future = clientNodeA.services.startProtocol("notary-change", protocol) 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. // - The transaction type is not a notary change transaction at all.
} }
fun issueState(node: AbstractNode): StateAndRef<*> { fun issueState(node: AbstractNode, notaryNode: AbstractNode): StateAndRef<*> {
val tx = DummyContract.generateInitial(node.info.identity.ref(0), Random().nextInt(), DUMMY_NOTARY) val tx = DummyContract.generateInitial(node.info.legalIdentity.ref(0), Random().nextInt(), notaryNode.info.notaryIdentity)
tx.signWith(node.storage.myLegalIdentityKey) val nodeKey = node.services.legalIdentityKey
tx.signWith(DUMMY_NOTARY_KEY) tx.signWith(nodeKey)
val notaryKeyPair = notaryNode.services.notaryIdentityKey
tx.signWith(notaryKeyPair)
val stx = tx.toSignedTransaction() val stx = tx.toSignedTransaction()
node.services.recordTransactions(listOf(stx)) node.services.recordTransactions(listOf(stx))
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0)) return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
} }
fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode): StateAndRef<DummyContract.MultiOwnerState> { fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode, notaryNode: AbstractNode): StateAndRef<DummyContract.MultiOwnerState> {
val state = TransactionState(DummyContract.MultiOwnerState(0, val state = TransactionState(DummyContract.MultiOwnerState(0,
listOf(nodeA.info.identity.owningKey, nodeB.info.identity.owningKey)), DUMMY_NOTARY) listOf(nodeA.info.legalIdentity.owningKey, nodeB.info.legalIdentity.owningKey)), notaryNode.info.notaryIdentity)
val tx = TransactionType.NotaryChange.Builder(DUMMY_NOTARY).withItems(state) val tx = TransactionType.NotaryChange.Builder(notaryNode.info.notaryIdentity).withItems(state)
tx.signWith(nodeA.storage.myLegalIdentityKey) val nodeAKey = nodeA.services.legalIdentityKey
tx.signWith(nodeB.storage.myLegalIdentityKey) val nodeBKey = nodeB.services.legalIdentityKey
tx.signWith(DUMMY_NOTARY_KEY) tx.signWith(nodeAKey)
tx.signWith(nodeBKey)
val notaryKeyPair = notaryNode.services.notaryIdentityKey
tx.signWith(notaryKeyPair)
val stx = tx.toSignedTransaction() val stx = tx.toSignedTransaction()
nodeA.services.recordTransactions(listOf(stx)) nodeA.services.recordTransactions(listOf(stx))
nodeB.services.recordTransactions(listOf(stx)) nodeB.services.recordTransactions(listOf(stx))
@ -119,10 +124,11 @@ fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode): StateAndRef<
return stateAndRef return stateAndRef
} }
fun issueInvalidState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateAndRef<*> { fun issueInvalidState(node: AbstractNode, notary: Party): StateAndRef<*> {
val tx = DummyContract.generateInitial(node.info.identity.ref(0), Random().nextInt(), notary) val tx = DummyContract.generateInitial(node.info.legalIdentity.ref(0), Random().nextInt(), notary)
tx.setTime(Instant.now(), 30.seconds) tx.setTime(Instant.now(), 30.seconds)
tx.signWith(node.storage.myLegalIdentityKey) val nodeKey = node.services.legalIdentityKey
tx.signWith(nodeKey)
val stx = tx.toSignedTransaction(false) val stx = tx.toSignedTransaction(false)
node.services.recordTransactions(listOf(stx)) node.services.recordTransactions(listOf(stx))
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0)) return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))

View File

@ -1,6 +1,9 @@
package com.r3corda.node.services package com.r3corda.node.services
import com.google.common.util.concurrent.ListenableFuture 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.contracts.TransactionType
import com.r3corda.core.node.services.ServiceInfo import com.r3corda.core.node.services.ServiceInfo
import com.r3corda.core.crypto.DigitalSignature 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.transactions.SignedTransaction
import com.r3corda.core.utilities.DUMMY_NOTARY import com.r3corda.core.utilities.DUMMY_NOTARY
import com.r3corda.core.utilities.DUMMY_NOTARY_KEY 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.network.NetworkMapService
import com.r3corda.node.services.transactions.SimpleNotaryService import com.r3corda.node.services.transactions.SimpleNotaryService
import com.r3corda.protocols.NotaryError import com.r3corda.protocols.NotaryError
@ -18,6 +22,7 @@ import com.r3corda.testing.node.MockNetwork
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import java.time.Instant import java.time.Instant
import java.util.*
import java.util.concurrent.ExecutionException import java.util.concurrent.ExecutionException
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
@ -33,7 +38,7 @@ class NotaryServiceTests {
notaryNode = net.createNode( notaryNode = net.createNode(
legalName = DUMMY_NOTARY.name, legalName = DUMMY_NOTARY.name,
keyPair = DUMMY_NOTARY_KEY, 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) clientNode = net.createNode(networkMapAddress = notaryNode.info.address, keyPair = MINI_CORP_KEY)
net.runNetwork() // Clear network map registration messages net.runNetwork() // Clear network map registration messages
} }
@ -41,7 +46,7 @@ class NotaryServiceTests {
@Test fun `should sign a unique transaction with a valid timestamp`() { @Test fun `should sign a unique transaction with a valid timestamp`() {
val stx = run { val stx = run {
val inputState = issueState(clientNode) 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.setTime(Instant.now(), 30.seconds)
tx.signWith(clientNode.keyPair!!) tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false) tx.toSignedTransaction(false)
@ -55,7 +60,7 @@ class NotaryServiceTests {
@Test fun `should sign a unique transaction without a timestamp`() { @Test fun `should sign a unique transaction without a timestamp`() {
val stx = run { val stx = run {
val inputState = issueState(clientNode) 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.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false) tx.toSignedTransaction(false)
} }
@ -68,7 +73,7 @@ class NotaryServiceTests {
@Test fun `should report error for transaction with an invalid timestamp`() { @Test fun `should report error for transaction with an invalid timestamp`() {
val stx = run { val stx = run {
val inputState = issueState(clientNode) 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.setTime(Instant.now().plusSeconds(3600), 30.seconds)
tx.signWith(clientNode.keyPair!!) tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false) tx.toSignedTransaction(false)
@ -84,7 +89,7 @@ class NotaryServiceTests {
@Test fun `should report conflict for a duplicate transaction`() { @Test fun `should report conflict for a duplicate transaction`() {
val stx = run { val stx = run {
val inputState = issueState(clientNode) 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.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false) tx.toSignedTransaction(false)
} }
@ -109,4 +114,15 @@ class NotaryServiceTests {
net.runNetwork() net.runNetwork()
return future 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))
}
} }

View File

@ -1,14 +1,13 @@
package com.r3corda.node.services package com.r3corda.node.services
import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.ListenableFuture
import com.r3corda.core.contracts.Command import com.r3corda.core.contracts.*
import com.r3corda.core.contracts.DummyContract
import com.r3corda.core.contracts.TransactionType
import com.r3corda.core.crypto.DigitalSignature import com.r3corda.core.crypto.DigitalSignature
import com.r3corda.core.node.services.ServiceInfo import com.r3corda.core.node.services.ServiceInfo
import com.r3corda.core.transactions.SignedTransaction import com.r3corda.core.transactions.SignedTransaction
import com.r3corda.core.utilities.DUMMY_NOTARY import com.r3corda.core.utilities.DUMMY_NOTARY
import com.r3corda.core.utilities.DUMMY_NOTARY_KEY 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.network.NetworkMapService
import com.r3corda.node.services.transactions.ValidatingNotaryService import com.r3corda.node.services.transactions.ValidatingNotaryService
import com.r3corda.protocols.NotaryError import com.r3corda.protocols.NotaryError
@ -20,6 +19,7 @@ import com.r3corda.testing.node.MockNetwork
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import java.util.*
import java.util.concurrent.ExecutionException import java.util.concurrent.ExecutionException
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
@ -34,7 +34,7 @@ class ValidatingNotaryServiceTests {
notaryNode = net.createNode( notaryNode = net.createNode(
legalName = DUMMY_NOTARY.name, legalName = DUMMY_NOTARY.name,
keyPair = DUMMY_NOTARY_KEY, 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) clientNode = net.createNode(networkMapAddress = notaryNode.info.address, keyPair = MINI_CORP_KEY)
net.runNetwork() // Clear network map registration messages net.runNetwork() // Clear network map registration messages
@ -42,8 +42,8 @@ class ValidatingNotaryServiceTests {
@Test fun `should report error for invalid transaction dependency`() { @Test fun `should report error for invalid transaction dependency`() {
val stx = run { val stx = run {
val inputState = issueInvalidState(clientNode) val inputState = issueInvalidState(clientNode, notaryNode.info.notaryIdentity)
val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState) val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
tx.signWith(clientNode.keyPair!!) tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false) tx.toSignedTransaction(false)
} }
@ -61,7 +61,7 @@ class ValidatingNotaryServiceTests {
val inputState = issueState(clientNode) val inputState = issueState(clientNode)
val command = Command(DummyContract.Commands.Move(), expectedMissingKey) 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.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false) tx.toSignedTransaction(false)
} }
@ -82,4 +82,15 @@ class ValidatingNotaryServiceTests {
net.runNetwork() net.runNetwork()
return future 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))
}
} }

View File

@ -84,7 +84,7 @@ class VaultWithCashTest {
fun `issue and spend total correctly and irrelevant ignored`() { fun `issue and spend total correctly and irrelevant ignored`() {
databaseTransaction(database) { databaseTransaction(database) {
// A tx that sends us money. // A tx that sends us money.
val freshKey = services.storageService.myLegalIdentityKey val freshKey = services.keyManagementService.freshKey()
val usefulTX = TransactionType.General.Builder(null).apply { val usefulTX = TransactionType.General.Builder(null).apply {
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), freshKey.public, DUMMY_NOTARY) Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), freshKey.public, DUMMY_NOTARY)
signWith(MEGA_CORP_KEY) signWith(MEGA_CORP_KEY)
@ -122,7 +122,7 @@ class VaultWithCashTest {
@Test @Test
fun `branching LinearStates fails to verify`() { fun `branching LinearStates fails to verify`() {
databaseTransaction(database) { databaseTransaction(database) {
val freshKey = services.storageService.myLegalIdentityKey val freshKey = services.keyManagementService.freshKey()
val linearId = UniqueIdentifier() val linearId = UniqueIdentifier()
// Issue a linear state // Issue a linear state
@ -142,7 +142,7 @@ class VaultWithCashTest {
@Test @Test
fun `sequencing LinearStates works`() { fun `sequencing LinearStates works`() {
databaseTransaction(database) { databaseTransaction(database) {
val freshKey = services.storageService.myLegalIdentityKey val freshKey = services.keyManagementService.freshKey()
val linearId = UniqueIdentifier() val linearId = UniqueIdentifier()

View File

@ -33,8 +33,8 @@ class DataVendingServiceTests {
@Test @Test
fun `notify of transaction`() { fun `notify of transaction`() {
val (vaultServiceNode, registerNode) = network.createTwoNodes() val (vaultServiceNode, registerNode) = network.createTwoNodes()
val beneficiary = vaultServiceNode.services.storageService.myLegalIdentityKey.public val beneficiary = vaultServiceNode.info.legalIdentity.owningKey
val deposit = registerNode.services.storageService.myLegalIdentity.ref(1) val deposit = registerNode.info.legalIdentity.ref(1)
network.runNetwork() network.runNetwork()
// Generate an issuance transaction // Generate an issuance transaction
@ -42,7 +42,8 @@ class DataVendingServiceTests {
Cash().generateIssue(ptx, Amount(100, Issued(deposit, USD)), beneficiary, DUMMY_NOTARY) Cash().generateIssue(ptx, Amount(100, Issued(deposit, USD)), beneficiary, DUMMY_NOTARY)
// Complete the cash transaction, and then manually relay it // 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() val tx = ptx.toSignedTransaction()
assertEquals(0, vaultServiceNode.services.vaultService.currentVault.states.toList().size) assertEquals(0, vaultServiceNode.services.vaultService.currentVault.states.toList().size)
@ -61,7 +62,7 @@ class DataVendingServiceTests {
@Test @Test
fun `notify failure`() { fun `notify failure`() {
val (vaultServiceNode, registerNode) = network.createTwoNodes() val (vaultServiceNode, registerNode) = network.createTwoNodes()
val beneficiary = vaultServiceNode.services.storageService.myLegalIdentityKey.public val beneficiary = vaultServiceNode.info.legalIdentity.owningKey
val deposit = MEGA_CORP.ref(1) val deposit = MEGA_CORP.ref(1)
network.runNetwork() network.runNetwork()
@ -70,7 +71,8 @@ class DataVendingServiceTests {
Cash().generateIssue(ptx, Amount(100, Issued(deposit, USD)), beneficiary, DUMMY_NOTARY) 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 // 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) val tx = ptx.toSignedTransaction(false)
assertEquals(0, vaultServiceNode.services.vaultService.currentVault.states.toList().size) assertEquals(0, vaultServiceNode.services.vaultService.currentVault.states.toList().size)
@ -82,7 +84,7 @@ class DataVendingServiceTests {
private fun MockNode.sendNotifyTx(tx: SignedTransaction, walletServiceNode: MockNode) { private fun MockNode.sendNotifyTx(tx: SignedTransaction, walletServiceNode: MockNode) {
walletServiceNode.services.registerProtocolInitiator(NotifyTxProtocol::class, ::NotifyTransactionHandler) 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() network.runNetwork()
} }

View File

@ -60,7 +60,7 @@ class StateMachineManagerTests {
fun `protocol restarted just after receiving payload`() { fun `protocol restarted just after receiving payload`() {
node2.services.registerProtocolInitiator(SendProtocol::class) { ReceiveThenSuspendProtocol(it) } node2.services.registerProtocolInitiator(SendProtocol::class) { ReceiveThenSuspendProtocol(it) }
val payload = random63BitValue() 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 // 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 // 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`() { fun `protocol loaded from checkpoint will respond to messages from before start`() {
val payload = random63BitValue() val payload = random63BitValue()
node1.services.registerProtocolInitiator(ReceiveThenSuspendProtocol::class) { SendProtocol(payload, it) } 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.smm.add("test", receiveProtocol) // Prepare checkpointed receive protocol
node2.stop() // kill receiver node2.stop() // kill receiver
val restoredProtocol = node2.restartAndGetRestoredProtocol<ReceiveThenSuspendProtocol>(node1.info.address) val restoredProtocol = node2.restartAndGetRestoredProtocol<ReceiveThenSuspendProtocol>(node1.info.address)
@ -135,7 +135,7 @@ class StateMachineManagerTests {
} }
// Kick off first send and receive // 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()) assertEquals(1, node2.checkpointStorage.checkpoints().count())
// Restart node and thus reload the checkpoint and resend the message with same UUID // Restart node and thus reload the checkpoint and resend the message with same UUID
node2.stop() node2.stop()
@ -165,7 +165,7 @@ class StateMachineManagerTests {
node2.services.registerProtocolInitiator(SendProtocol::class) { ReceiveThenSuspendProtocol(it) } node2.services.registerProtocolInitiator(SendProtocol::class) { ReceiveThenSuspendProtocol(it) }
node3.services.registerProtocolInitiator(SendProtocol::class) { ReceiveThenSuspendProtocol(it) } node3.services.registerProtocolInitiator(SendProtocol::class) { ReceiveThenSuspendProtocol(it) }
val payload = random63BitValue() 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() net.runNetwork()
val node2Protocol = node2.getSingleProtocol<ReceiveThenSuspendProtocol>().first val node2Protocol = node2.getSingleProtocol<ReceiveThenSuspendProtocol>().first
val node3Protocol = node3.getSingleProtocol<ReceiveThenSuspendProtocol>().first val node3Protocol = node3.getSingleProtocol<ReceiveThenSuspendProtocol>().first
@ -181,7 +181,7 @@ class StateMachineManagerTests {
val node3Payload = random63BitValue() val node3Payload = random63BitValue()
node2.services.registerProtocolInitiator(ReceiveThenSuspendProtocol::class) { SendProtocol(node2Payload, it) } node2.services.registerProtocolInitiator(ReceiveThenSuspendProtocol::class) { SendProtocol(node2Payload, it) }
node3.services.registerProtocolInitiator(ReceiveThenSuspendProtocol::class) { SendProtocol(node3Payload, 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) node1.smm.add("multiple-receive", multiReceiveProtocol)
net.runNetwork(1) // session handshaking net.runNetwork(1) // session handshaking
// have the messages arrive in reverse order of receive // have the messages arrive in reverse order of receive
@ -195,7 +195,7 @@ class StateMachineManagerTests {
@Test @Test
fun `exception thrown on other side`() { fun `exception thrown on other side`() {
node2.services.registerProtocolInitiator(ReceiveThenSuspendProtocol::class) { ExceptionProtocol } 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() net.runNetwork()
assertThatThrownBy { future.get() }.hasCauseInstanceOf(ProtocolSessionException::class.java) assertThatThrownBy { future.get() }.hasCauseInstanceOf(ProtocolSessionException::class.java)
} }

View File

@ -406,11 +406,11 @@ private fun startNode(params: CliParams.RunNode, networkMap: SingleMessageRecipi
val networkMapId = val networkMapId =
when (params.node) { when (params.node) {
IRSDemoNode.NodeA -> { IRSDemoNode.NodeA -> {
advertisedServices = setOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type)) advertisedServices = setOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type))
null null
} }
IRSDemoNode.NodeB -> { IRSDemoNode.NodeB -> {
advertisedServices = setOf(ServiceInfo(NodeInterestRates.Type)) advertisedServices = setOf(ServiceInfo(NodeInterestRates.type))
networkMap networkMap
} }
} }
@ -475,7 +475,7 @@ private fun loadConfigFile(baseDir: Path, configFile: Path, configOverrides: Map
private fun createIdentities(nodeConf: NodeConfiguration) { private fun createIdentities(nodeConf: NodeConfiguration) {
val mockNetwork = MockNetwork(false) 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.start()
node.stop() node.stop()
} }

View File

@ -78,12 +78,12 @@ fun main(args: Array<String>) {
} }
node.networkMapRegistrationFuture.get() node.networkMapRegistrationFuture.get()
val notaryNode = node.services.networkMapCache.notaryNodes[0] 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. // Make a garbage transaction that includes a rate fix.
val tx = TransactionType.General.Builder(notaryNode.identity) val tx = TransactionType.General.Builder(notaryNode.notaryIdentity)
tx.addOutputState(TransactionState(Cash.State(1500.DOLLARS `issued by` node.storage.myLegalIdentity.ref(1), node.storage.myLegalIdentityKey.public), notaryNode.identity)) 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.identity, fixOf, expectedRate, rateTolerance) val protocol = RatesFixProtocol(tx, rateOracle.serviceIdentities(InterestRateSwap.oracleType).first(), fixOf, expectedRate, rateTolerance)
node.services.startProtocol("demo.ratefix", protocol).get() node.services.startProtocol("demo.ratefix", protocol).get()
node.stop() node.stop()

View File

@ -141,7 +141,7 @@ fun main(args: Array<String>) {
// 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 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. // the side that sticks around waiting for the seller.
val networkMapId = if (role == Role.BUYER) { val networkMapId = if (role == Role.BUYER) {
advertisedServices = setOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type)) advertisedServices = setOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type))
null null
} else { } else {
advertisedServices = emptySet() advertisedServices = emptySet()
@ -160,7 +160,7 @@ fun main(args: Array<String>) {
runBuyer(node, amount) runBuyer(node, amount)
} else { } else {
node.networkMapRegistrationFuture.success { 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) runSeller(node, amount, party)
} }
} }
@ -211,8 +211,8 @@ private fun runBuyer(node: Node, amount: Amount<Currency>) {
// TODO: At some point this demo should be extended to have a central bank node. // TODO: At some point this demo should be extended to have a central bank node.
databaseTransaction(node.database) { databaseTransaction(node.database) {
node.services.fillWithSomeTestCash(300000.DOLLARS, node.services.fillWithSomeTestCash(300000.DOLLARS,
outputNotary = node.info.identity, // In this demo, the buyer and notary are the same. outputNotary = node.info.notaryIdentity, // In this demo, the buyer and notary are on the same node, but need to use right key.
ownedBy = node.storage.myLegalIdentityKey.public) 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 // 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 notary: NodeInfo = serviceHub.networkMapCache.notaryNodes[0]
val buyer = TwoPartyTradeProtocol.Buyer( val buyer = TwoPartyTradeProtocol.Buyer(
otherSide, otherSide,
notary.identity, notary.notaryIdentity,
amount, amount,
CommercialPaper.State::class.java) CommercialPaper.State::class.java)
@ -304,7 +304,7 @@ private class TraderDemoProtocolSeller(val otherSide: Party,
progressTracker.currentStep = SELF_ISSUING progressTracker.currentStep = SELF_ISSUING
val notary: NodeInfo = serviceHub.networkMapCache.notaryNodes[0] val notary: NodeInfo = serviceHub.networkMapCache.notaryNodes[0]
val cpOwnerKey = serviceHub.storageService.myLegalIdentityKey val cpOwnerKey = serviceHub.legalIdentityKey
val commercialPaper = selfIssueSomeCommercialPaper(cpOwnerKey.public, notary) val commercialPaper = selfIssueSomeCommercialPaper(cpOwnerKey.public, notary)
progressTracker.currentStep = TRADING progressTracker.currentStep = TRADING
@ -330,7 +330,7 @@ private class TraderDemoProtocolSeller(val otherSide: Party,
val issuance: SignedTransaction = run { val issuance: SignedTransaction = run {
val tx = CommercialPaper().generateIssue(party.ref(1, 2, 3), 1100.DOLLARS `issued by` DUMMY_CASH_ISSUER, 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. // 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. // Now make a dummy transaction that moves it to a new key, just to show that resolving dependencies works.
val move: SignedTransaction = run { 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) CommercialPaper().generateMove(builder, issuance.tx.outRef(0), ownedBy)
builder.signWith(keyPair) builder.signWith(keyPair)
val notarySignature = subProtocol(NotaryProtocol.Client(builder.toSignedTransaction(false))) val notarySignature = subProtocol(NotaryProtocol.Client(builder.toSignedTransaction(false)))

View File

@ -42,7 +42,7 @@ import javax.annotation.concurrent.ThreadSafe
* for signing. * for signing.
*/ */
object NodeInterestRates { 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. * 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. * The Service that wraps [Oracle] and handles messages/network interaction/request scrubbing.
*/ */
class Service(services: ServiceHubInternal) : AcceptsFileUpload, SingletonSerializeAsToken() { class Service(val services: ServiceHubInternal) : AcceptsFileUpload, SingletonSerializeAsToken() {
val ss = services.storageService val oracle: Oracle by lazy {
val oracle = Oracle(ss.myLegalIdentity, ss.myLegalIdentityKey, services.clock) val myNodeInfo = services.myInfo
val myIdentity = myNodeInfo.serviceIdentities(type).first()
init { val mySigningKey = services.keyManagementService.toKeyPair(myIdentity.owningKey)
services.registerProtocolInitiator(FixSignProtocol::class) { FixSignHandler(it, oracle) } Oracle(myIdentity, mySigningKey, services.clock)
services.registerProtocolInitiator(FixQueryProtocol::class) { FixQueryHandler(it, oracle) }
} }
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<Unit>() { private class FixSignHandler(val otherParty: Party, val service: Service) : ProtocolLogic<Unit>() {
@Suspendable @Suspendable
override fun call() { override fun call() {
val request = receive<SignRequest>(otherParty).unwrap { it } val request = receive<SignRequest>(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<Unit>() { private class FixQueryHandler(val otherParty: Party, val service: Service) : ProtocolLogic<Unit>() {
companion object { companion object {
object RECEIVED : ProgressTracker.Step("Received fix request") object RECEIVED : ProgressTracker.Step("Received fix request")
@ -89,7 +95,7 @@ object NodeInterestRates {
@Suspendable @Suspendable
override fun call(): Unit { override fun call(): Unit {
val request = receive<QueryRequest>(otherParty).unwrap { it } val request = receive<QueryRequest>(otherParty).unwrap { it }
val answers = oracle.query(request.queries, request.deadline) val answers = service.oracle.query(request.queries, request.deadline)
progressTracker.currentStep = SENDING progressTracker.currentStep = SENDING
send(otherParty, answers) send(otherParty, answers)
} }

View File

@ -111,7 +111,7 @@ fun main(args: Array<String>) {
// 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 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. // the side that sticks around waiting for the sender.
val networkMapId = if (role == Role.SENDER) { val networkMapId = if (role == Role.SENDER) {
advertisedServices = setOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type)) advertisedServices = setOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type))
null null
} else { } else {
advertisedServices = emptySet() advertisedServices = emptySet()
@ -131,7 +131,7 @@ fun main(args: Array<String>) {
node.networkMapRegistrationFuture.success { node.networkMapRegistrationFuture.success {
// Pause a moment to give the network map time to update // Pause a moment to give the network map time to update
Thread.sleep(100L) 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) runSender(node, party)
} }
} }

View File

@ -62,14 +62,15 @@ object AutoOfferProtocol {
@Suspendable @Suspendable
override fun call(): SignedTransaction { override fun call(): SignedTransaction {
require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" } 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 // need to pick which ever party is not us
val otherParty = notUs(dealToBeOffered.parties).single() val otherParty = notUs(dealToBeOffered.parties).single()
progressTracker.currentStep = DEALING progressTracker.currentStep = DEALING
val myKey = serviceHub.legalIdentityKey
val instigator = Instigator( val instigator = Instigator(
otherParty, otherParty,
AutoOffer(notary, dealToBeOffered), AutoOffer(notary, dealToBeOffered),
serviceHub.storageService.myLegalIdentityKey, myKey,
progressTracker.getChildProgressTracker(DEALING)!! progressTracker.getChildProgressTracker(DEALING)!!
) )
val stx = subProtocol(instigator) val stx = subProtocol(instigator)
@ -79,7 +80,7 @@ object AutoOfferProtocol {
private fun notUs(parties: List<Party>): List<Party> { private fun notUs(parties: List<Party>): List<Party> {
val notUsParties: MutableList<Party> = arrayListOf() val notUsParties: MutableList<Party> = arrayListOf()
for (party in parties) { for (party in parties) {
if (serviceHub.storageService.myLegalIdentity != party) { if (serviceHub.myInfo.legalIdentity != party) {
notUsParties.add(party) notUsParties.add(party)
} }
} }

View File

@ -66,7 +66,7 @@ object ExitServerProtocol {
if (recipient.address is MockNetworkMapCache.MockAddress) { if (recipient.address is MockNetworkMapCache.MockAddress) {
// Ignore // Ignore
} else { } else {
send(recipient.identity, ExitMessage(exitCode)) send(recipient.legalIdentity, ExitMessage(exitCode))
} }
} }
} }

View File

@ -60,7 +60,7 @@ object UpdateBusinessDayProtocol {
if (recipient.address is MockNetworkMapCache.MockAddress) { if (recipient.address is MockNetworkMapCache.MockAddress) {
// Ignore // Ignore
} else { } else {
send(recipient.identity, UpdateBusinessDayMessage(date)) send(recipient.legalIdentity, UpdateBusinessDayMessage(date))
} }
} }
} }

View File

@ -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. // 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. // TODO: We should revisit this in post-Excalibur cleanup and fix, e.g. by introducing an interface.
val irs = om.readValue<InterestRateSwap.State>(javaClass.getResource("trade.json")) val irs = om.readValue<InterestRateSwap.State>(javaClass.getResource("trade.json"))
irs.fixedLeg.fixedRatePayer = node1.info.identity irs.fixedLeg.fixedRatePayer = node1.info.legalIdentity
irs.floatingLeg.floatingRatePayer = node2.info.identity irs.floatingLeg.floatingRatePayer = node2.info.legalIdentity
val acceptorTx = node2.initiateSingleShotProtocol(Instigator::class) { Acceptor(it) }.flatMap { it.resultFuture } val acceptorTx = node2.initiateSingleShotProtocol(Instigator::class) { Acceptor(it) }.flatMap { it.resultFuture }
showProgressFor(listOf(node1, node2)) showProgressFor(listOf(node1, node2))
showConsensusFor(listOf(node1, node2, regulators[0])) 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) val instigatorTx = node1.services.startProtocol("instigator", instigator)
return Futures.allAsList(instigatorTx, acceptorTx).flatMap { instigatorTx } return Futures.allAsList(instigatorTx, acceptorTx).flatMap { instigatorTx }

View File

@ -87,7 +87,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
object NetworkMapNodeFactory : MockNetwork.Factory { object NetworkMapNodeFactory : MockNetwork.Factory {
override fun create(config: NodeConfiguration, network: MockNetwork, override fun create(config: NodeConfiguration, network: MockNetwork,
networkMapAddr: SingleMessageRecipient?, advertisedServices: Set<ServiceInfo>, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { networkMapAddr: SingleMessageRecipient?, advertisedServices: Set<ServiceInfo>, 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 // TODO: create a base class that provides a default implementation
val cfg = object : NodeConfiguration { val cfg = object : NodeConfiguration {
@ -109,7 +109,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
object NotaryNodeFactory : MockNetwork.Factory { object NotaryNodeFactory : MockNetwork.Factory {
override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?,
advertisedServices: Set<ServiceInfo>, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { advertisedServices: Set<ServiceInfo>, 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 // TODO: create a base class that provides a default implementation
val cfg = object : NodeConfiguration { val cfg = object : NodeConfiguration {
@ -130,7 +130,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
object RatesOracleFactory : MockNetwork.Factory { object RatesOracleFactory : MockNetwork.Factory {
override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?, override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?,
advertisedServices: Set<ServiceInfo>, id: Int, keyPair: KeyPair?): MockNetwork.MockNode { advertisedServices: Set<ServiceInfo>, 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 // TODO: create a base class that provides a default implementation
val cfg = object : NodeConfiguration { val cfg = object : NodeConfiguration {
@ -188,12 +188,12 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
val network = MockNetwork(networkSendManuallyPumped, runAsync) val network = MockNetwork(networkSendManuallyPumped, runAsync)
// This one must come first. // This one must come first.
val networkMap: SimulatedNode 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 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<SimulatedNode> = listOf(network.createNode(networkMap.info.address, start = false, nodeFactory = RegulatorFactory) as SimulatedNode) val regulators: List<SimulatedNode> = listOf(network.createNode(networkMap.info.address, start = false, nodeFactory = RegulatorFactory) as SimulatedNode)
val ratesOracle: 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. // All nodes must be in one of these two lists for the purposes of the visualiser tool.
val serviceProviders: List<SimulatedNode> = listOf(notary, ratesOracle, networkMap) val serviceProviders: List<SimulatedNode> = listOf(notary, ratesOracle, networkMap)

View File

@ -33,14 +33,16 @@ class TradeSimulation(runAsync: Boolean, latencyInjector: InMemoryMessagingNetwo
val buyer = banks[buyerBankIndex] val buyer = banks[buyerBankIndex]
val seller = banks[sellerBankIndex] val seller = banks[sellerBankIndex]
buyer.services.fillWithSomeTestCash(1500.DOLLARS, notary.info.identity) buyer.services.fillWithSomeTestCash(1500.DOLLARS, notary.info.notaryIdentity)
val issuance = run { val issuance = run {
val tx = CommercialPaper().generateIssue(seller.info.identity.ref(1, 2, 3), 1100.DOLLARS `issued by` DUMMY_CASH_ISSUER, val tx = CommercialPaper().generateIssue(seller.info.legalIdentity.ref(1, 2, 3), 1100.DOLLARS `issued by` DUMMY_CASH_ISSUER,
Instant.now() + 10.days, notary.info.identity) Instant.now() + 10.days, notary.info.notaryIdentity)
tx.setTime(Instant.now(), 30.seconds) tx.setTime(Instant.now(), 30.seconds)
tx.signWith(notary.storage.myLegalIdentityKey) val notaryKey = notary.services.notaryIdentityKey
tx.signWith(seller.storage.myLegalIdentityKey) val sellerKey = seller.services.legalIdentityKey
tx.signWith(notaryKey)
tx.signWith(sellerKey)
tx.toSignedTransaction(true) tx.toSignedTransaction(true)
} }
seller.services.recordTransactions(issuance) seller.services.recordTransactions(issuance)
@ -48,15 +50,16 @@ class TradeSimulation(runAsync: Boolean, latencyInjector: InMemoryMessagingNetwo
val amount = 1000.DOLLARS val amount = 1000.DOLLARS
val buyerFuture = buyer.initiateSingleShotProtocol(Seller::class) { 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 } }.flatMap { it.resultFuture }
val sellerKey = seller.services.legalIdentityKey
val sellerProtocol = Seller( val sellerProtocol = Seller(
buyer.info.identity, buyer.info.legalIdentity,
notary.info, notary.info,
issuance.tx.outRef<OwnableState>(0), issuance.tx.outRef<OwnableState>(0),
amount, amount,
seller.storage.myLegalIdentityKey) sellerKey)
showConsensusFor(listOf(buyer, seller, notary)) showConsensusFor(listOf(buyer, seller, notary))
showProgressFor(listOf(buyer, seller)) showProgressFor(listOf(buyer, seller))

View File

@ -11,6 +11,7 @@ import com.r3corda.core.contracts.TransactionType
import com.r3corda.core.contracts.`with notary` import com.r3corda.core.contracts.`with notary`
import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.Party
import com.r3corda.core.crypto.generateKeyPair 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.DUMMY_NOTARY
import com.r3corda.core.utilities.LogHelper import com.r3corda.core.utilities.LogHelper
import com.r3corda.testing.node.MockNetwork import com.r3corda.testing.node.MockNetwork
@ -141,13 +142,14 @@ class NodeInterestRatesTest {
@Test @Test
fun network() { fun network() {
val net = MockNetwork() 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) { databaseTransaction(n2.database) {
n2.findService<NodeInterestRates.Service>().oracle.knownFixes = TEST_DATA n2.findService<NodeInterestRates.Service>().oracle.knownFixes = TEST_DATA
} }
val tx = TransactionType.General.Builder(null) val tx = TransactionType.General.Builder(null)
val fixOf = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M") 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") LogHelper.setLevel("rates")
net.runNetwork() net.runNetwork()
val future = n1.services.startProtocol("rates", protocol) val future = n1.services.startProtocol("rates", protocol)

View File

@ -20,8 +20,8 @@ class MockNetworkMapCache() : com.r3corda.node.services.network.InMemoryNetworkM
init { init {
val mockNodeA = NodeInfo(MockAddress("bankC:8080"), Party("Bank C", DummyPublicKey("Bank C"))) val mockNodeA = NodeInfo(MockAddress("bankC:8080"), Party("Bank C", DummyPublicKey("Bank C")))
val mockNodeB = NodeInfo(MockAddress("bankD:8080"), Party("Bank D", DummyPublicKey("Bank D"))) val mockNodeB = NodeInfo(MockAddress("bankD:8080"), Party("Bank D", DummyPublicKey("Bank D")))
registeredNodes[mockNodeA.identity] = mockNodeA registeredNodes[mockNodeA.legalIdentity] = mockNodeA
registeredNodes[mockNodeB.identity] = mockNodeB registeredNodes[mockNodeB.legalIdentity] = mockNodeB
runWithoutMapService() runWithoutMapService()
} }
@ -31,7 +31,7 @@ class MockNetworkMapCache() : com.r3corda.node.services.network.InMemoryNetworkM
*/ */
@VisibleForTesting @VisibleForTesting
fun addRegistration(node: NodeInfo) { 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. * not a change being received.
*/ */
@VisibleForTesting @VisibleForTesting
fun deleteRegistration(identity: Party) : Boolean { fun deleteRegistration(legalIdentity: Party) : Boolean {
return registeredNodes.remove(identity) != null return registeredNodes.remove(legalIdentity) != null
} }
} }

View File

@ -107,7 +107,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
override fun makeVaultService(): VaultService = InMemoryVaultService(services) 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?) { override fun startMessagingService(cordaRPCOps: CordaRPCOps?) {
// Nothing to do // Nothing to do
@ -129,7 +129,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
override fun start(): MockNode { override fun start(): MockNode {
super.start() super.start()
mockNet.identities.add(storage.myLegalIdentity) mockNet.identities.add(info.legalIdentity)
return this return this
} }
@ -212,7 +212,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
fun createTwoNodes(nodeFactory: Factory = defaultFactory, notaryKeyPair: KeyPair? = null): Pair<MockNode, MockNode> { fun createTwoNodes(nodeFactory: Factory = defaultFactory, notaryKeyPair: KeyPair? = null): Pair<MockNode, MockNode> {
require(nodes.isEmpty()) require(nodes.isEmpty())
return Pair( 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) 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 { fun createSomeNodes(numPartyNodes: Int = 2, nodeFactory: Factory = defaultFactory, notaryKeyPair: KeyPair? = DUMMY_NOTARY_KEY): BasketOfNodes {
require(nodes.isEmpty()) 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, val notaryNode = createNode(mapNode.info.address, nodeFactory = nodeFactory, keyPair = notaryKeyPair,
advertisedServices = ServiceInfo(SimpleNotaryService.Type)) advertisedServices = ServiceInfo(SimpleNotaryService.type))
val nodes = ArrayList<MockNode>() val nodes = ArrayList<MockNode>()
repeat(numPartyNodes) { repeat(numPartyNodes) {
nodes += createPartyNode(mapNode.info.address) 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 { 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 { fun createPartyNode(networkMapAddr: SingleMessageRecipient, legalName: String? = null, keyPair: KeyPair? = null): MockNode {

View File

@ -7,6 +7,8 @@ import com.r3corda.core.crypto.SecureHash
import com.r3corda.core.crypto.generateKeyPair import com.r3corda.core.crypto.generateKeyPair
import com.r3corda.core.crypto.sha256 import com.r3corda.core.crypto.sha256
import com.r3corda.core.messaging.MessagingService 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.ServiceHub
import com.r3corda.core.node.services.* import com.r3corda.core.node.services.*
import com.r3corda.core.protocols.ProtocolLogic 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 identityService: MockIdentityService = MockIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_NOTARY))
override val keyManagementService: MockKeyManagementService = MockKeyManagementService(key) 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 networkMapCache: NetworkMapCache get() = throw UnsupportedOperationException()
override val clock: Clock get() = throw UnsupportedOperationException() override val clock: Clock get() = throw UnsupportedOperationException()
override val schedulerService: SchedulerService get() = throw UnsupportedOperationException() override val schedulerService: SchedulerService get() = throw UnsupportedOperationException()
override val myInfo: NodeInfo get() = NodeInfo(object : SingleMessageRecipient {} , Party("MegaCorp", key.public))
} }
@ThreadSafe @ThreadSafe
@ -150,8 +153,6 @@ open class MockTransactionStorage : TransactionStorage {
@ThreadSafe @ThreadSafe
class MockStorageService(override val attachments: AttachmentStorage = MockAttachmentStorage(), class MockStorageService(override val attachments: AttachmentStorage = MockAttachmentStorage(),
override val validatedTransactions: TransactionStorage = MockTransactionStorage(), 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()) override val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage = MockStateMachineRecordedTransactionMappingStorage())
: SingletonSerializeAsToken(), TxWritableStorageService : SingletonSerializeAsToken(), TxWritableStorageService