Remove advertised services from NodeInfo (#1521)

* Remove advertisedServices from NodeInfo.

Introduce notaryIdentities in NetworkMapCache, that will be filled in
later from NetworkParameters. Clean up NetworkMapCache API. Expose
notaryIdentities through RPC. For now we assume as temporary solution
that notaries in NetworkMap have to contain "notary" in name.

* Further clean up of NetworkMapCache API

Remve partyNodes. Introduce getAllNodeInfos function

* Remove notaryIdentity from ServiceHub

* Address Shams review comments

* Address Andrius review comments

* Add comments, cleanup

* Fixes

* Address comments

* Yet another commit with comments addressed

* Move ServiceType and ServiceInfo to node-api

Add changelog entry. Address rest of comments.

* Minor comments
This commit is contained in:
Katarzyna Streich
2017-09-20 13:19:57 +01:00
committed by josecoll
parent 6887947a4d
commit fd57cf1c0c
122 changed files with 467 additions and 615 deletions

View File

@ -9,6 +9,7 @@ import net.corda.core.crypto.keys
import net.corda.core.flows.FlowInitiator import net.corda.core.flows.FlowInitiator
import net.corda.core.flows.StateMachineRunId import net.corda.core.flows.StateMachineRunId
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.internal.bufferUntilSubscribed import net.corda.core.internal.bufferUntilSubscribed
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.StateMachineTransactionMapping import net.corda.core.messaging.StateMachineTransactionMapping
@ -16,7 +17,6 @@ import net.corda.core.messaging.StateMachineUpdate
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.NetworkMapCache
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
@ -27,7 +27,7 @@ import net.corda.finance.flows.CashExitFlow
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.node.services.network.NetworkMapService import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.* import net.corda.testing.*
@ -39,7 +39,7 @@ import rx.Observable
class NodeMonitorModelTest : DriverBasedTest() { class NodeMonitorModelTest : DriverBasedTest() {
lateinit var aliceNode: NodeInfo lateinit var aliceNode: NodeInfo
lateinit var bobNode: NodeInfo lateinit var bobNode: NodeInfo
lateinit var notaryNode: NodeInfo lateinit var notaryParty: Party
lateinit var rpc: CordaRPCOps lateinit var rpc: CordaRPCOps
lateinit var rpcBob: CordaRPCOps lateinit var rpcBob: CordaRPCOps
@ -59,11 +59,9 @@ class NodeMonitorModelTest : DriverBasedTest() {
startFlowPermission<CashExitFlow>()) startFlowPermission<CashExitFlow>())
) )
val aliceNodeFuture = startNode(providedName = ALICE.name, rpcUsers = listOf(cashUser)) val aliceNodeFuture = startNode(providedName = ALICE.name, rpcUsers = listOf(cashUser))
val notaryNodeFuture = startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))) val notaryHandle = startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))).getOrThrow()
val aliceNodeHandle = aliceNodeFuture.getOrThrow() val aliceNodeHandle = aliceNodeFuture.getOrThrow()
val notaryNodeHandle = notaryNodeFuture.getOrThrow()
aliceNode = aliceNodeHandle.nodeInfo aliceNode = aliceNodeHandle.nodeInfo
notaryNode = notaryNodeHandle.nodeInfo
newNode = { nodeName -> startNode(providedName = nodeName).getOrThrow().nodeInfo } newNode = { nodeName -> startNode(providedName = nodeName).getOrThrow().nodeInfo }
val monitor = NodeMonitorModel() val monitor = NodeMonitorModel()
stateMachineTransactionMapping = monitor.stateMachineTransactionMapping.bufferUntilSubscribed() stateMachineTransactionMapping = monitor.stateMachineTransactionMapping.bufferUntilSubscribed()
@ -75,6 +73,7 @@ class NodeMonitorModelTest : DriverBasedTest() {
monitor.register(aliceNodeHandle.configuration.rpcAddress!!, cashUser.username, cashUser.password, initialiseSerialization = false) monitor.register(aliceNodeHandle.configuration.rpcAddress!!, cashUser.username, cashUser.password, initialiseSerialization = false)
rpc = monitor.proxyObservable.value!! rpc = monitor.proxyObservable.value!!
notaryParty = notaryHandle.nodeInfo.legalIdentities[1]
val bobNodeHandle = startNode(providedName = BOB.name, rpcUsers = listOf(cashUser)).getOrThrow() val bobNodeHandle = startNode(providedName = BOB.name, rpcUsers = listOf(cashUser)).getOrThrow()
bobNode = bobNodeHandle.nodeInfo bobNode = bobNodeHandle.nodeInfo
@ -87,9 +86,9 @@ class NodeMonitorModelTest : DriverBasedTest() {
@Test @Test
fun `network map update`() { fun `network map update`() {
newNode(CHARLIE.name) val charlieNode = newNode(CHARLIE.name)
networkMapUpdates.filter { !it.node.advertisedServices.any { it.info.type.isNotary() } } val nonServiceIdentities = aliceNode.legalIdentitiesAndCerts + bobNode.legalIdentitiesAndCerts + charlieNode.legalIdentitiesAndCerts
.filter { !it.node.advertisedServices.any { it.info.type == NetworkMapService.type } } networkMapUpdates.filter { it.node.legalIdentitiesAndCerts.any { it in nonServiceIdentities } }
.expectEvents(isStrict = false) { .expectEvents(isStrict = false) {
sequence( sequence(
// TODO : Add test for remove when driver DSL support individual node shutdown. // TODO : Add test for remove when driver DSL support individual node shutdown.
@ -111,7 +110,7 @@ class NodeMonitorModelTest : DriverBasedTest() {
rpc.startFlow(::CashIssueFlow, rpc.startFlow(::CashIssueFlow,
Amount(100, USD), Amount(100, USD),
OpaqueBytes(ByteArray(1, { 1 })), OpaqueBytes(ByteArray(1, { 1 })),
notaryNode.notaryIdentity notaryParty
) )
vaultUpdates.expectEvents(isStrict = false) { vaultUpdates.expectEvents(isStrict = false) {
@ -132,7 +131,7 @@ class NodeMonitorModelTest : DriverBasedTest() {
@Test @Test
fun `cash issue and move`() { fun `cash issue and move`() {
val (_, issueIdentity) = rpc.startFlow(::CashIssueFlow, 100.DOLLARS, OpaqueBytes.of(1), notaryNode.notaryIdentity).returnValue.getOrThrow() val (_, issueIdentity) = rpc.startFlow(::CashIssueFlow, 100.DOLLARS, OpaqueBytes.of(1), notaryParty).returnValue.getOrThrow()
rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, bobNode.chooseIdentity()).returnValue.getOrThrow() rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, bobNode.chooseIdentity()).returnValue.getOrThrow()
var issueSmId: StateMachineRunId? = null var issueSmId: StateMachineRunId? = null
@ -191,7 +190,7 @@ class NodeMonitorModelTest : DriverBasedTest() {
val signaturePubKeys = stx.sigs.map { it.by }.toSet() val signaturePubKeys = stx.sigs.map { it.by }.toSet()
// Alice and Notary signed // Alice and Notary signed
require(issueIdentity!!.owningKey.isFulfilledBy(signaturePubKeys)) require(issueIdentity!!.owningKey.isFulfilledBy(signaturePubKeys))
require(notaryNode.notaryIdentity.owningKey.isFulfilledBy(signaturePubKeys)) require(notaryParty.owningKey.isFulfilledBy(signaturePubKeys))
moveTx = stx moveTx = stx
} }
) )

View File

@ -7,8 +7,8 @@ import javafx.collections.FXCollections
import javafx.collections.ObservableList import javafx.collections.ObservableList
import net.corda.client.jfx.utils.fold import net.corda.client.jfx.utils.fold
import net.corda.client.jfx.utils.map import net.corda.client.jfx.utils.map
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.AnonymousParty import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.services.NetworkMapCache.MapChange import net.corda.core.node.services.NetworkMapCache.MapChange
import java.security.PublicKey import java.security.PublicKey
@ -33,25 +33,13 @@ class NetworkIdentityModel {
private val identityCache = CacheBuilder.newBuilder() private val identityCache = CacheBuilder.newBuilder()
.build<PublicKey, ObservableValue<NodeInfo?>>(CacheLoader.from { .build<PublicKey, ObservableValue<NodeInfo?>>(CacheLoader.from {
publicKey -> publicKey ->
publicKey?.let { rpcProxy.map { it?.nodeIdentityFromParty(AnonymousParty(publicKey)) } } publicKey?.let { rpcProxy.map { it?.nodeInfoFromParty(AnonymousParty(publicKey)) } }
}) })
val parties: ObservableList<NodeInfo> = networkIdentities.filtered { !it.isCordaService() } val notaries: ObservableList<PartyAndCertificate> = FXCollections.observableList(rpcProxy.value?.notaryIdentities())
val notaries: ObservableList<NodeInfo> = networkIdentities.filtered { it.advertisedServices.any { it.info.type.isNotary() } } val notaryNodes: ObservableList<NodeInfo> = FXCollections.observableList(notaries.map { rpcProxy.value?.nodeInfoFromParty(it.party) })
val myNodeInfo = rpcProxy.map { it?.nodeInfo() } // TODO Used only for querying for advertised services, remove with services. val parties: ObservableList<NodeInfo> = networkIdentities.filtered { it.legalIdentitiesAndCerts.all { it !in notaries } }
val myIdentity = myNodeInfo.map { it?.legalIdentitiesAndCerts?.first()?.party } val myIdentity = rpcProxy.map { it?.nodeInfo()?.legalIdentitiesAndCerts?.first()?.party }
private fun NodeInfo.isCordaService(): Boolean {
// TODO: better way to identify Corda service?
return advertisedServices.any { it.info.type.isNetworkMap() || it.info.type.isNotary() }
}
fun partyFromPublicKey(publicKey: PublicKey): ObservableValue<NodeInfo?> = identityCache[publicKey] fun partyFromPublicKey(publicKey: PublicKey): ObservableValue<NodeInfo?> = identityCache[publicKey]
//TODO rebase fix
// // TODO: Use Identity Service in service hub instead?
// fun lookup(publicKey: PublicKey): ObservableValue<PartyAndCertificate?> {
// val party = parties.flatMap { it.legalIdentitiesAndCerts }.firstOrNull { publicKey in it.owningKey.keys } ?:
// notaries.flatMap { it.legalIdentitiesAndCerts }.firstOrNull { it.owningKey.keys.any { it == publicKey }}
// return ReadOnlyObjectWrapper(party)
// }
} }

View File

@ -5,6 +5,7 @@ import net.corda.client.rpc.CordaRPCClient
import net.corda.client.rpc.CordaRPCClientConfiguration import net.corda.client.rpc.CordaRPCClientConfiguration
import net.corda.core.contracts.ContractState import net.corda.core.contracts.ContractState
import net.corda.core.flows.StateMachineRunId import net.corda.core.flows.StateMachineRunId
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.messaging.* import net.corda.core.messaging.*
import net.corda.core.node.services.NetworkMapCache.MapChange import net.corda.core.node.services.NetworkMapCache.MapChange
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
@ -45,6 +46,7 @@ class NodeMonitorModel {
val networkMap: Observable<MapChange> = networkMapSubject val networkMap: Observable<MapChange> = networkMapSubject
val proxyObservable = SimpleObjectProperty<CordaRPCOps?>() val proxyObservable = SimpleObjectProperty<CordaRPCOps?>()
lateinit var notaryIdentities: List<PartyAndCertificate>
/** /**
* Register for updates to/from a given vault. * Register for updates to/from a given vault.
@ -60,6 +62,7 @@ class NodeMonitorModel {
) )
val connection = client.start(username, password) val connection = client.start(username, password)
val proxy = connection.proxy val proxy = connection.proxy
notaryIdentities = proxy.notaryIdentities()
val (stateMachines, stateMachineUpdates) = proxy.stateMachinesFeed() val (stateMachines, stateMachineUpdates) = proxy.stateMachinesFeed()
// Extract the flow tracking stream // Extract the flow tracking stream

View File

@ -5,7 +5,6 @@ import net.corda.core.concurrent.CordaFuture;
import net.corda.core.contracts.Amount; import net.corda.core.contracts.Amount;
import net.corda.core.messaging.CordaRPCOps; import net.corda.core.messaging.CordaRPCOps;
import net.corda.core.messaging.FlowHandle; import net.corda.core.messaging.FlowHandle;
import net.corda.core.node.services.ServiceInfo;
import net.corda.core.utilities.OpaqueBytes; import net.corda.core.utilities.OpaqueBytes;
import net.corda.finance.flows.AbstractCashFlow; import net.corda.finance.flows.AbstractCashFlow;
import net.corda.finance.flows.CashIssueFlow; import net.corda.finance.flows.CashIssueFlow;
@ -14,6 +13,7 @@ import net.corda.finance.schemas.*;
import net.corda.node.internal.Node; import net.corda.node.internal.Node;
import net.corda.node.internal.StartedNode; import net.corda.node.internal.StartedNode;
import net.corda.node.services.transactions.ValidatingNotaryService; import net.corda.node.services.transactions.ValidatingNotaryService;
import net.corda.nodeapi.ServiceInfo;
import net.corda.nodeapi.User; import net.corda.nodeapi.User;
import net.corda.testing.CoreTestUtils; import net.corda.testing.CoreTestUtils;
import net.corda.testing.node.NodeBasedTest; import net.corda.testing.node.NodeBasedTest;

View File

@ -6,7 +6,6 @@ import net.corda.core.messaging.FlowProgressHandle
import net.corda.core.messaging.StateMachineUpdate import net.corda.core.messaging.StateMachineUpdate
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.messaging.startTrackedFlow import net.corda.core.messaging.startTrackedFlow
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.finance.DOLLARS import net.corda.finance.DOLLARS
@ -20,6 +19,7 @@ import net.corda.finance.schemas.CashSchemaV1
import net.corda.node.internal.Node import net.corda.node.internal.Node
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.ALICE import net.corda.testing.ALICE

View File

@ -9,6 +9,7 @@ import net.corda.core.flows.StateMachineRunId
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.NetworkMapCache
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
@ -212,6 +213,11 @@ interface CordaRPCOps : RPCOps {
*/ */
fun nodeInfo(): NodeInfo fun nodeInfo(): NodeInfo
/**
* Returns network's notary identities, assuming this will not change while the node is running.
*/
fun notaryIdentities(): List<PartyAndCertificate>
/* /*
* Add note(s) to an existing Vault transaction * Add note(s) to an existing Vault transaction
*/ */
@ -284,11 +290,11 @@ interface CordaRPCOps : RPCOps {
fun registeredFlows(): List<String> fun registeredFlows(): List<String>
/** /**
* Returns a node's identity from the network map cache, where known. * Returns a node's info from the network map cache, where known.
* *
* @return the node info if available. * @return the node info if available.
*/ */
fun nodeIdentityFromParty(party: AbstractParty): NodeInfo? fun nodeInfoFromParty(party: AbstractParty): NodeInfo?
/** /**
* Clear all network map data from local node cache. * Clear all network map data from local node cache.

View File

@ -2,37 +2,24 @@ package net.corda.core.node
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.ServiceType
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
/**
* Information for an advertised service including the service specific identity information.
* The identity can be used in flows and is distinct from the Node's legalIdentity
*/
@CordaSerializable
data class ServiceEntry(val info: ServiceInfo, val identity: PartyAndCertificate)
/** /**
* 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.
* @param legalIdentitiesAndCerts is a non-empty list, where the first identity is assumed to be the default identity of the node.
*/ */
// TODO We currently don't support multi-IP/multi-identity nodes, we only left slots in the data structures. // TODO We currently don't support multi-IP/multi-identity nodes, we only left slots in the data structures.
@CordaSerializable @CordaSerializable
data class NodeInfo(val addresses: List<NetworkHostAndPort>, data class NodeInfo(val addresses: List<NetworkHostAndPort>,
/** Non-empty list of all the identities, plus certificates, that belong to this node. */
val legalIdentitiesAndCerts: List<PartyAndCertificate>, val legalIdentitiesAndCerts: List<PartyAndCertificate>,
val platformVersion: Int, val platformVersion: Int,
val advertisedServices: List<ServiceEntry> = emptyList(),
val serial: Long val serial: Long
) { ) {
init { init {
require(legalIdentitiesAndCerts.isNotEmpty()) { "Node should have at least one legal identity" } require(legalIdentitiesAndCerts.isNotEmpty()) { "Node should have at least one legal identity" }
} }
// TODO This part will be removed with services removal.
val notaryIdentity: Party get() = advertisedServices.single { it.info.type.isNotary() }.identity.party
@Transient private var _legalIdentities: List<Party>? = null @Transient private var _legalIdentities: List<Party>? = null
val legalIdentities: List<Party> get() { val legalIdentities: List<Party> get() {
return _legalIdentities ?: legalIdentitiesAndCerts.map { it.party }.also { _legalIdentities = it } return _legalIdentities ?: legalIdentitiesAndCerts.map { it.party }.also { _legalIdentities = it }
@ -40,8 +27,4 @@ data class NodeInfo(val addresses: List<NetworkHostAndPort>,
/** Returns true if [party] is one of the identities of this node, else false. */ /** Returns true if [party] is one of the identities of this node, else false. */
fun isLegalIdentity(party: Party): Boolean = party in legalIdentities fun isLegalIdentity(party: Party): Boolean = party in legalIdentities
fun serviceIdentities(type: ServiceType): List<Party> {
return advertisedServices.mapNotNull { if (it.info.type.isSubTypeOf(type)) it.identity.party else null }
}
} }

View File

@ -143,7 +143,9 @@ interface ServiceHub : ServicesForResolution {
* If the key is actually a [net.corda.core.crypto.CompositeKey], the first leaf key hosted on this node * If the key is actually a [net.corda.core.crypto.CompositeKey], the first leaf key hosted on this node
* will be used to create the signature. * will be used to create the signature.
*/ */
val notaryIdentityKey: PublicKey get() = this.myInfo.notaryIdentity.owningKey // TODO Remove that from ServiceHub, we could take that information from a transaction notary field and figure out what key to use from that.
// But, it's separate PR.
val notaryIdentityKey: PublicKey
// Helper method to construct an initial partially signed transaction from a [TransactionBuilder]. // Helper method to construct an initial partially signed transaction from a [TransactionBuilder].
private fun signInitialTransaction(builder: TransactionBuilder, publicKey: PublicKey, signatureMetadata: SignatureMetadata): SignedTransaction { private fun signInitialTransaction(builder: TransactionBuilder, publicKey: PublicKey, signatureMetadata: SignatureMetadata): SignedTransaction {

View File

@ -5,10 +5,10 @@ import net.corda.core.contracts.Contract
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.randomOrNull import net.corda.core.internal.randomOrNull
import net.corda.core.messaging.DataFeed import net.corda.core.messaging.DataFeed
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.ServiceEntry
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import rx.Observable import rx.Observable
@ -31,18 +31,9 @@ interface NetworkMapCache {
data class Modified(override val node: NodeInfo, val previousNode: NodeInfo) : MapChange() data class Modified(override val node: NodeInfo, val previousNode: NodeInfo) : MapChange()
} }
/** A list of all nodes the cache is aware of */ /** A list of notary services available on the network */
val partyNodes: List<NodeInfo> // TODO this list will be taken from NetworkParameters distributed by NetworkMap.
/** A list of nodes that advertise a network map service */ val notaryIdentities: List<PartyAndCertificate>
val networkMapNodes: List<NodeInfo>
/** A list of nodes that advertise a notary service */
val notaryNodes: List<NodeInfo> get() = getNodesWithService(ServiceType.notary)
/**
* A list of nodes that advertise a regulatory service. Identifying the correct regulator for a trade is outside
* the scope of the network map service, and this is intended solely as a sanity check on configuration stored
* elsewhere.
*/
val regulatorNodes: List<NodeInfo> get() = getNodesWithService(ServiceType.regulator)
/** Tracks changes to the network map cache */ /** Tracks changes to the network map cache */
val changed: Observable<MapChange> val changed: Observable<MapChange>
/** Future to track completion of the NetworkMapService registration. */ /** Future to track completion of the NetworkMapService registration. */
@ -54,26 +45,6 @@ interface NetworkMapCache {
*/ */
fun track(): DataFeed<List<NodeInfo>, MapChange> fun track(): DataFeed<List<NodeInfo>, MapChange>
/** Get the collection of nodes which advertise a specific service. */
fun getNodesWithService(serviceType: ServiceType): List<NodeInfo> {
return partyNodes.filter { it.advertisedServices.any { it.info.type.isSubTypeOf(serviceType) } }
}
// TODO It will be removed with services + part of these functions will get merged into database backed NetworkMapCache
fun getPeersWithService(serviceType: ServiceType): List<ServiceEntry> {
return partyNodes.fold(ArrayList<ServiceEntry>()) {
acc, elem -> acc.addAll(elem.advertisedServices.filter { it.info.type.isSubTypeOf(serviceType)})
acc
}
}
/**
* Get a recommended node that advertises a service, and is suitable for the specified contract and parties.
* Implementations might understand, for example, the correct regulator to use for specific contracts/parties,
* or the appropriate oracle for a contract.
*/
fun getRecommended(type: ServiceType, contract: Contract, vararg party: Party): NodeInfo? = getNodesWithService(type).firstOrNull()
/** /**
* Look up the node info for a specific party. Will attempt to de-anonymise the party if applicable; if the party * Look up the node info for a specific party. Will attempt to de-anonymise the party if applicable; if the party
* is anonymised and the well known party cannot be resolved, it is impossible ot identify the node and therefore this * is anonymised and the well known party cannot be resolved, it is impossible ot identify the node and therefore this
@ -86,81 +57,47 @@ interface NetworkMapCache {
fun getNodeByLegalIdentity(party: AbstractParty): NodeInfo? fun getNodeByLegalIdentity(party: AbstractParty): NodeInfo?
/** Look up the node info for a legal name. */ /** Look up the node info for a legal name. */
fun getNodeByLegalName(principal: CordaX500Name): NodeInfo? fun getNodeByLegalName(name: CordaX500Name): NodeInfo?
/** Look up the node info for a host and port. */ /** Look up the node info for a host and port. */
fun getNodeByAddress(address: NetworkHostAndPort): NodeInfo? fun getNodeByAddress(address: NetworkHostAndPort): NodeInfo?
fun getPeerByLegalName(principal: CordaX500Name): Party? = getNodeByLegalName(principal)?.let { fun getPeerByLegalName(name: CordaX500Name): Party? = getNodeByLegalName(name)?.let {
it.legalIdentitiesAndCerts.singleOrNull { it.name == principal }?.party it.legalIdentitiesAndCerts.singleOrNull { it.name == name }?.party
} }
/** Return all [NodeInfo]s the node currently is aware of (including ourselves). */
val allNodes: List<NodeInfo>
/** /**
* Look up the node infos for a specific peer key.
* In general, nodes can advertise multiple identities: a legal identity, and separate identities for each of * In general, nodes can advertise multiple identities: a legal identity, and separate identities for each of
* the services it provides. In case of a distributed service run by multiple nodes each participant advertises * the services it provides. In case of a distributed service run by multiple nodes each participant advertises
* the identity of the *whole group*. * the identity of the *whole group*.
*/ */
/** Look up the node infos for a specific peer key. */
fun getNodesByLegalIdentityKey(identityKey: PublicKey): List<NodeInfo> fun getNodesByLegalIdentityKey(identityKey: PublicKey): List<NodeInfo>
/** Look up all nodes advertising the service owned by [publicKey] */
fun getNodesByAdvertisedServiceIdentityKey(publicKey: PublicKey): List<NodeInfo> {
return partyNodes.filter { it.advertisedServices.any { it.identity.owningKey == publicKey } }
}
/** Returns information about the party, which may be a specific node or a service */ /** Returns information about the party, which may be a specific node or a service */
fun getPartyInfo(party: Party): PartyInfo? fun getPartyInfo(party: Party): PartyInfo?
/** Gets a notary identity by the given name. */ /** Gets a notary identity by the given name. */
fun getNotary(principal: CordaX500Name): Party? { fun getNotary(name: CordaX500Name): Party? = notaryIdentities.firstOrNull { it.name == name }?.party
val notaryNode = notaryNodes.filter {
it.advertisedServices.any { it.info.type.isSubTypeOf(ServiceType.notary) && it.info.name == principal }
}.randomOrNull()
return notaryNode?.notaryIdentity
}
/** /**
* Returns a notary identity advertised by any of the nodes on the network (chosen at random) * Returns a notary identity advertised by any of the nodes on the network (chosen at random)
* @param type Limits the result to notaries of the specified type (optional) * @param type Limits the result to notaries of the specified type (optional)
*/ */
fun getAnyNotary(type: ServiceType? = null): Party? { fun getAnyNotary(): Party? = notaryIdentities.randomOrNull()?.party
val nodes = if (type == null) {
notaryNodes
} else {
require(type != ServiceType.notary && type.isSubTypeOf(ServiceType.notary)) {
"The provided type must be a specific notary sub-type"
}
notaryNodes.filter { it.advertisedServices.any { it.info.type == type } }
}
return nodes.randomOrNull()?.notaryIdentity
}
/**
* Returns a service identity advertised by one of the nodes on the network
* @param type Specifies the type of the service
*/
fun getAnyServiceOfType(type: ServiceType): Party? {
for (node in partyNodes) {
val serviceIdentities = node.serviceIdentities(type)
if (serviceIdentities.isNotEmpty()) {
return serviceIdentities.randomOrNull()
}
}
return null;
}
/** Checks whether a given party is an advertised notary identity */ /** Checks whether a given party is an advertised notary identity */
fun isNotary(party: Party): Boolean = notaryNodes.any { it.notaryIdentity == party } fun isNotary(party: Party): Boolean = notaryIdentities.any { party == it.party }
/** Checks whether a given party is an advertised validating notary identity */ /** Checks whether a given party is an validating notary identity */
fun isValidatingNotary(party: Party): Boolean { fun isValidatingNotary(party: Party): Boolean {
val notary = notaryNodes.firstOrNull { it.notaryIdentity == party } val notary = notaryIdentities.firstOrNull { it.party == party } ?:
?: throw IllegalArgumentException("No notary found with identity $party. This is most likely caused " + throw IllegalArgumentException("No notary found with identity $party.")
"by using the notary node's legal identity instead of its advertised notary identity. " + return !notary.name.toString().contains("corda.notary.simple", true) // TODO This implementation will change after introducing of NetworkParameters.
"Your options are: ${notaryNodes.map { "\"${it.notaryIdentity.name}\"" }.joinToString()}.")
return notary.advertisedServices.any { it.info.type.isValidatingNotary() }
} }
/** /**
* Clear all network map data from local node cache. * Clear all network map data from local node cache.
*/ */

View File

@ -2,7 +2,6 @@ package net.corda.core.schemas
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.ServiceEntry
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
@ -39,10 +38,6 @@ object NodeInfoSchemaV1 : MappedSchema(
@Column(name = "platform_version") @Column(name = "platform_version")
val platformVersion: Int, val platformVersion: Int,
@Column(name = "advertised_services")
@ElementCollection
var advertisedServices: List<DBServiceEntry> = emptyList(),
/** /**
* serial is an increasing value which represents the version of [NodeInfo]. * serial is an increasing value which represents the version of [NodeInfo].
* Not expected to be sequential, but later versions of the registration must have higher values * Not expected to be sequential, but later versions of the registration must have higher values
@ -56,9 +51,6 @@ object NodeInfoSchemaV1 : MappedSchema(
this.addresses.map { it.toHostAndPort() }, this.addresses.map { it.toHostAndPort() },
(this.legalIdentitiesAndCerts.filter { it.isMain } + this.legalIdentitiesAndCerts.filter { !it.isMain }).map { it.toLegalIdentityAndCert() }, (this.legalIdentitiesAndCerts.filter { it.isMain } + this.legalIdentitiesAndCerts.filter { !it.isMain }).map { it.toLegalIdentityAndCert() },
this.platformVersion, this.platformVersion,
this.advertisedServices.map {
it.serviceEntry?.deserialize<ServiceEntry>() ?: throw IllegalStateException("Service entry shouldn't be null")
},
this.serial this.serial
) )
} }
@ -85,12 +77,6 @@ object NodeInfoSchemaV1 : MappedSchema(
} }
} }
@Embeddable // TODO To be removed with services.
data class DBServiceEntry(
@Column(length = 65535)
val serviceEntry: ByteArray? = null
)
/** /**
* PartyAndCertificate entity (to be replaced by referencing final Identity Schema). * PartyAndCertificate entity (to be replaced by referencing final Identity Schema).
*/ */

View File

@ -8,9 +8,9 @@ import net.corda.core.identity.Party
import net.corda.core.internal.FetchAttachmentsFlow import net.corda.core.internal.FetchAttachmentsFlow
import net.corda.core.internal.FetchDataFlow import net.corda.core.internal.FetchDataFlow
import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.network.NetworkMapService import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.persistence.NodeAttachmentService import net.corda.node.services.persistence.NodeAttachmentService

View File

@ -16,6 +16,7 @@ import net.corda.testing.chooseIdentity
import net.corda.testing.chooseIdentityAndCert import net.corda.testing.chooseIdentityAndCert
import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import org.junit.After import org.junit.After
@ -39,8 +40,8 @@ class CollectSignaturesFlowTests {
a = nodes.partyNodes[0] a = nodes.partyNodes[0]
b = nodes.partyNodes[1] b = nodes.partyNodes[1]
c = nodes.partyNodes[2] c = nodes.partyNodes[2]
notary = nodes.notaryNode.info.notaryIdentity
mockNet.runNetwork() mockNet.runNetwork()
notary = a.services.getDefaultNotary()
a.internals.ensureRegistered() a.internals.ensureRegistered()
} }
@ -86,7 +87,7 @@ class CollectSignaturesFlowTests {
@Suspendable @Suspendable
override fun call(): SignedTransaction { override fun call(): SignedTransaction {
val state = receive<DummyContract.MultiOwnerState>(otherParty).unwrap { it } val state = receive<DummyContract.MultiOwnerState>(otherParty).unwrap { it }
val notary = serviceHub.networkMapCache.notaryNodes.single().notaryIdentity val notary = serviceHub.getDefaultNotary()
val myInputKeys = state.participants.map { it.owningKey } val myInputKeys = state.participants.map { it.owningKey }
val myKeys = myInputKeys + (identities[ourIdentity] ?: ourIdentity).owningKey val myKeys = myInputKeys + (identities[ourIdentity] ?: ourIdentity).owningKey
@ -107,7 +108,7 @@ class CollectSignaturesFlowTests {
class Initiator(val state: DummyContract.MultiOwnerState) : FlowLogic<SignedTransaction>() { class Initiator(val state: DummyContract.MultiOwnerState) : FlowLogic<SignedTransaction>() {
@Suspendable @Suspendable
override fun call(): SignedTransaction { override fun call(): SignedTransaction {
val notary = serviceHub.networkMapCache.notaryNodes.single().notaryIdentity val notary = serviceHub.getDefaultNotary()
val myInputKeys = state.participants.map { it.owningKey } val myInputKeys = state.participants.map { it.owningKey }
val command = Command(DummyContract.Commands.Create(), myInputKeys) val command = Command(DummyContract.Commands.Create(), myInputKeys)
val builder = TransactionBuilder(notary).withItems(StateAndContract(state, DUMMY_PROGRAM_ID), command) val builder = TransactionBuilder(notary).withItems(StateAndContract(state, DUMMY_PROGRAM_ID), command)

View File

@ -25,6 +25,7 @@ import net.corda.testing.RPCDriverExposedDSLInterface
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.contracts.DummyContractV2 import net.corda.testing.contracts.DummyContractV2
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.rpcDriver import net.corda.testing.rpcDriver
import net.corda.testing.rpcTestUser import net.corda.testing.rpcTestUser
@ -54,9 +55,8 @@ class ContractUpgradeFlowTest {
mockNet.runNetwork() mockNet.runNetwork()
a.internals.ensureRegistered() a.internals.ensureRegistered()
notary = nodes.notaryNode.info.notaryIdentity notary = a.services.getDefaultNotary()
val nodeIdentity = nodes.notaryNode.info.legalIdentitiesAndCerts.single { it.party == notary }
val nodeIdentity = nodes.notaryNode.info.legalIdentitiesAndCerts.single { it.party == nodes.notaryNode.info.notaryIdentity }
a.database.transaction { a.database.transaction {
a.services.identityService.verifyAndRegisterIdentity(nodeIdentity) a.services.identityService.verifyAndRegisterIdentity(nodeIdentity)
} }

View File

@ -10,6 +10,7 @@ import net.corda.finance.contracts.asset.Cash
import net.corda.testing.ALICE import net.corda.testing.ALICE
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import org.junit.After import org.junit.After
@ -31,9 +32,9 @@ class FinalityFlowTests {
val nodes = mockNet.createSomeNodes(2) val nodes = mockNet.createSomeNodes(2)
nodeA = nodes.partyNodes[0] nodeA = nodes.partyNodes[0]
nodeB = nodes.partyNodes[1] nodeB = nodes.partyNodes[1]
notary = nodes.notaryNode.info.notaryIdentity
mockNet.runNetwork() mockNet.runNetwork()
nodeA.internals.ensureRegistered() nodeA.internals.ensureRegistered()
notary = nodeA.services.getDefaultNotary()
} }
@After @After

View File

@ -13,6 +13,7 @@ import net.corda.testing.ALICE
import net.corda.testing.BOB import net.corda.testing.BOB
import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
@ -47,7 +48,8 @@ class IdentitySyncFlowTests {
// Alice issues then pays some cash to a new confidential identity that Bob doesn't know about // Alice issues then pays some cash to a new confidential identity that Bob doesn't know about
val anonymous = true val anonymous = true
val ref = OpaqueBytes.of(0x01) val ref = OpaqueBytes.of(0x01)
val issueFlow = aliceNode.services.startFlow(CashIssueAndPaymentFlow(1000.DOLLARS, ref, alice, anonymous, notaryNode.services.myInfo.notaryIdentity)) val notary = aliceNode.services.getDefaultNotary()
val issueFlow = aliceNode.services.startFlow(CashIssueAndPaymentFlow(1000.DOLLARS, ref, alice, anonymous, notary))
val issueTx = issueFlow.resultFuture.getOrThrow().stx val issueTx = issueFlow.resultFuture.getOrThrow().stx
val confidentialIdentity = issueTx.tx.outputs.map { it.data }.filterIsInstance<Cash.State>().single().owner val confidentialIdentity = issueTx.tx.outputs.map { it.data }.filterIsInstance<Cash.State>().single().owner
assertNull(bobNode.database.transaction { bobNode.services.identityService.partyFromAnonymous(confidentialIdentity) }) assertNull(bobNode.database.transaction { bobNode.services.identityService.partyFromAnonymous(confidentialIdentity) })

View File

@ -9,6 +9,7 @@ import net.corda.finance.GBP
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import org.junit.After import org.junit.After
@ -32,9 +33,9 @@ class ManualFinalityFlowTests {
nodeA = nodes.partyNodes[0] nodeA = nodes.partyNodes[0]
nodeB = nodes.partyNodes[1] nodeB = nodes.partyNodes[1]
nodeC = nodes.partyNodes[2] nodeC = nodes.partyNodes[2]
notary = nodes.notaryNode.info.notaryIdentity
mockNet.runNetwork() mockNet.runNetwork()
nodeA.internals.ensureRegistered() nodeA.internals.ensureRegistered()
notary = nodeA.services.getDefaultNotary()
} }
@After @After

View File

@ -17,6 +17,7 @@ import net.corda.testing.MEGA_CORP_KEY
import net.corda.testing.MINI_CORP import net.corda.testing.MINI_CORP
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import org.junit.After import org.junit.After
@ -47,8 +48,8 @@ class ResolveTransactionsFlowTest {
b = nodes.partyNodes[1] b = nodes.partyNodes[1]
a.internals.registerInitiatedFlow(TestResponseFlow::class.java) a.internals.registerInitiatedFlow(TestResponseFlow::class.java)
b.internals.registerInitiatedFlow(TestResponseFlow::class.java) b.internals.registerInitiatedFlow(TestResponseFlow::class.java)
notary = nodes.notaryNode.info.notaryIdentity
mockNet.runNetwork() mockNet.runNetwork()
notary = a.services.getDefaultNotary()
} }
@After @After

View File

@ -1,38 +0,0 @@
package net.corda.core.node
import net.corda.core.identity.CordaX500Name
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.ServiceType
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
class ServiceInfoTests {
val serviceType = ServiceType.getServiceType("test", "service").getSubType("subservice")
val name = CordaX500Name(organisation = "Service.name", locality = "London", country = "GB")
@Test
fun `type and name encodes correctly`() {
assertEquals(ServiceInfo(serviceType, name).toString(), "$serviceType|$name")
}
@Test
fun `type and name parses correctly`() {
assertEquals(ServiceInfo.parse("$serviceType|$name"), ServiceInfo(serviceType, name))
}
@Test
fun `type only encodes correctly`() {
assertEquals(ServiceInfo(serviceType).toString(), "$serviceType")
}
@Test
fun `type only parses correctly`() {
assertEquals(ServiceInfo.parse("$serviceType"), ServiceInfo(serviceType))
}
@Test
fun `invalid encoding throws`() {
assertFailsWith<IllegalArgumentException> { ServiceInfo.parse("$serviceType|$name|something") }
}
}

View File

@ -10,11 +10,11 @@ import net.corda.core.identity.Party
import net.corda.core.internal.FetchAttachmentsFlow import net.corda.core.internal.FetchAttachmentsFlow
import net.corda.core.internal.FetchDataFlow import net.corda.core.internal.FetchDataFlow
import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.unwrap import net.corda.core.utilities.unwrap
import net.corda.node.internal.InitiatedFlowFactory import net.corda.node.internal.InitiatedFlowFactory
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.network.NetworkMapService import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.persistence.NodeAttachmentService import net.corda.node.services.persistence.NodeAttachmentService

View File

@ -6,6 +6,19 @@ from the previous milestone release.
UNRELEASED UNRELEASED
---------- ----------
* ``NodeInfo`` and ``NetworkMapCache`` changes:
* Removed ``NodeInfo::legalIdentity`` in preparation for handling of multiple identities. We left list of ``NodeInfo::legalIdentitiesAndCerts``,
the first identity still plays a special role of main node identity.
* We no longer support advertising services in network map. Removed ``NodeInfo::advertisedServices``, ``serviceIdentities``
and ``notaryIdentity``.
* Removed service methods from ``NetworkMapCache``: ``partyNodes``, ``networkMapNodes``, ``notaryNodes``, ``regulatorNodes``,
``getNodesWithService``, ``getPeersWithService``, ``getRecommended``, ``getNodesByAdvertisedServiceIdentityKey``,
``notaryNode``, ``getAnyServiceOfType``. To get all known ``NodeInfo``s call ``allNodes``.
* In preparation for ``NetworkMapService`` redesign and distributing notaries through ``NetworkParameters`` we added
``NetworkMapCache::notaryIdentities`` list to enable to lookup for notary parties known to the network. Related ``CordaRPCOps::notaryIdentities``
was introduced. Other special nodes parties like Oracles or Regulators need to be specified directly in CorDapp or flow.
* Moved ``ServiceType`` and ``ServiceInfo`` to ``net.corda.nodeapi`` package as services are only required on node startup.
* Adding enum support to the class carpenter * Adding enum support to the class carpenter
* ``ContractState::contract`` has been moved ``TransactionState::contract`` and it's type has changed to ``String`` in order to * ``ContractState::contract`` has been moved ``TransactionState::contract`` and it's type has changed to ``String`` in order to

View File

@ -3,7 +3,6 @@ package net.corda.docs
import net.corda.core.internal.concurrent.transpose import net.corda.core.internal.concurrent.transpose
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.messaging.vaultTrackBy import net.corda.core.messaging.vaultTrackBy
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
@ -12,6 +11,7 @@ import net.corda.finance.contracts.asset.Cash
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.* import net.corda.testing.*
@ -56,11 +56,12 @@ class IntegrationTestingTutorial {
// START 4 // START 4
val issueRef = OpaqueBytes.of(0) val issueRef = OpaqueBytes.of(0)
val notaryParty = aliceProxy.notaryIdentities().first().party
(1..10).map { i -> (1..10).map { i ->
aliceProxy.startFlow(::CashIssueFlow, aliceProxy.startFlow(::CashIssueFlow,
i.DOLLARS, i.DOLLARS,
issueRef, issueRef,
notary.nodeInfo.notaryIdentity notaryParty
).returnValue ).returnValue
}.transpose().getOrThrow() }.transpose().getOrThrow()
// We wait for all of the issuances to run before we start making payments // We wait for all of the issuances to run before we start making payments

View File

@ -10,7 +10,6 @@ import net.corda.core.flows.*;
import net.corda.core.identity.CordaX500Name; import net.corda.core.identity.CordaX500Name;
import net.corda.core.identity.Party; import net.corda.core.identity.Party;
import net.corda.core.internal.FetchDataFlow; import net.corda.core.internal.FetchDataFlow;
import net.corda.core.node.services.ServiceType;
import net.corda.core.node.services.Vault; import net.corda.core.node.services.Vault;
import net.corda.core.node.services.Vault.Page; import net.corda.core.node.services.Vault.Page;
import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria; import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria;
@ -54,11 +53,13 @@ public class FlowCookbookJava {
private final boolean arg1; private final boolean arg1;
private final int arg2; private final int arg2;
private final Party counterparty; private final Party counterparty;
private final Party regulator;
public InitiatorFlow(boolean arg1, int arg2, Party counterparty) { public InitiatorFlow(boolean arg1, int arg2, Party counterparty, Party regulator) {
this.arg1 = arg1; this.arg1 = arg1;
this.arg2 = arg2; this.arg2 = arg2;
this.counterparty = counterparty; this.counterparty = counterparty;
this.regulator = regulator;
} }
/*---------------------------------- /*----------------------------------
@ -124,11 +125,11 @@ public class FlowCookbookJava {
// We retrieve a notary from the network map. // We retrieve a notary from the network map.
// DOCSTART 1 // DOCSTART 1
Party specificNotary = getServiceHub().getNetworkMapCache().getNotary(new CordaX500Name("Notary Service", "London", "UK")); Party specificNotary = getServiceHub().getNetworkMapCache().getNotary(new CordaX500Name("Notary Service", "London", "UK"));
Party anyNotary = getServiceHub().getNetworkMapCache().getAnyNotary(null); Party anyNotary = getServiceHub().getNetworkMapCache().getAnyNotary();
// Unlike the first two methods, ``getNotaryNodes`` returns a // Unlike the first two methods, ``getNotaryNodes`` returns a
// ``List<NodeInfo>``. We have to extract the notary identity of // ``List<NodeInfo>``. We have to extract the notary identity of
// the node we want. // the node we want.
Party firstNotary = getServiceHub().getNetworkMapCache().getNotaryNodes().get(0).getNotaryIdentity(); Party firstNotary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0).getParty();
// DOCEND 1 // DOCEND 1
// We may also need to identify a specific counterparty. // We may also need to identify a specific counterparty.
@ -138,12 +139,6 @@ public class FlowCookbookJava {
Party keyedCounterparty = getServiceHub().getIdentityService().partyFromKey(dummyPubKey); Party keyedCounterparty = getServiceHub().getIdentityService().partyFromKey(dummyPubKey);
// DOCEND 2 // DOCEND 2
// Finally, we can use the map to identify nodes providing a
// specific service (e.g. a regulator or an oracle).
// DOCSTART 3
Party regulator = getServiceHub().getNetworkMapCache().getPeersWithService(ServiceType.Companion.getRegulator()).get(0).getIdentity().getParty();
// DOCEND 3
/*------------------------------ /*------------------------------
* SENDING AND RECEIVING DATA * * SENDING AND RECEIVING DATA *
------------------------------*/ ------------------------------*/
@ -528,7 +523,7 @@ public class FlowCookbookJava {
// We can also choose to send it to additional parties who aren't one // We can also choose to send it to additional parties who aren't one
// of the state's participants. // of the state's participants.
// DOCSTART 10 // DOCSTART 10
Set<Party> additionalParties = ImmutableSet.of(regulator, regulator); Set<Party> additionalParties = ImmutableSet.of(regulator);
SignedTransaction notarisedTx2 = subFlow(new FinalityFlow(ImmutableList.of(fullySignedTx), additionalParties, FINALISATION.childProgressTracker())).get(0); SignedTransaction notarisedTx2 = subFlow(new FinalityFlow(ImmutableList.of(fullySignedTx), additionalParties, FINALISATION.childProgressTracker())).get(0);
// DOCEND 10 // DOCEND 10

View File

@ -5,17 +5,18 @@ import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.messaging.vaultQueryBy import net.corda.core.messaging.vaultQueryBy
import net.corda.core.node.CordaPluginRegistry import net.corda.core.node.CordaPluginRegistry
import net.corda.core.node.services.ServiceInfo
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializationCustomization import net.corda.core.serialization.SerializationCustomization
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
import net.corda.finance.USD import net.corda.finance.USD
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.flows.CashExitFlow import net.corda.finance.flows.CashExitFlow
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.ALICE import net.corda.testing.ALICE
@ -56,6 +57,7 @@ fun main(args: Array<String>) {
// START 2 // START 2
val client = node.rpcClientToNode() val client = node.rpcClientToNode()
val proxy = client.start("user", "password").proxy val proxy = client.start("user", "password").proxy
proxy.waitUntilNetworkReady().getOrThrow()
thread { thread {
generateTransactions(proxy) generateTransactions(proxy)
@ -111,8 +113,7 @@ fun generateTransactions(proxy: CordaRPCOps) {
sum + state.state.data.amount.quantity sum + state.state.data.amount.quantity
} }
val issueRef = OpaqueBytes.of(0) val issueRef = OpaqueBytes.of(0)
val parties = proxy.networkMapSnapshot() val notary = proxy.notaryIdentities().first().party
val notary = parties.first { it.advertisedServices.any { it.info.type.isNotary() } }.notaryIdentity
val me = proxy.nodeInfo().legalIdentities.first() val me = proxy.nodeInfo().legalIdentities.first()
while (true) { while (true) {
Thread.sleep(1000) Thread.sleep(1000)

View File

@ -49,7 +49,7 @@ class MyValidatingNotaryFlow(otherSide: Party, service: MyCustomValidatingNotary
private fun checkSignatures(stx: SignedTransaction) { private fun checkSignatures(stx: SignedTransaction) {
try { try {
stx.verifySignaturesExcept(serviceHub.myInfo.notaryIdentity.owningKey) stx.verifySignaturesExcept(serviceHub.notaryIdentityKey)
} catch (e: SignatureException) { } catch (e: SignatureException) {
throw NotaryException(NotaryError.TransactionInvalid(e)) throw NotaryException(NotaryError.TransactionInvalid(e))
} }

View File

@ -20,6 +20,7 @@ import net.corda.finance.flows.AbstractCashFlow
import net.corda.finance.flows.CashException import net.corda.finance.flows.CashException
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.testing.getDefaultNotary
import java.util.* import java.util.*
// DOCSTART CustomVaultQuery // DOCSTART CustomVaultQuery
@ -132,7 +133,7 @@ object TopupIssuerFlow {
issueTo: Party, issueTo: Party,
issuerPartyRef: OpaqueBytes): AbstractCashFlow.Result { issuerPartyRef: OpaqueBytes): AbstractCashFlow.Result {
// TODO: pass notary in as request parameter // TODO: pass notary in as request parameter
val notaryParty = serviceHub.networkMapCache.notaryNodes[0].notaryIdentity val notaryParty = serviceHub.networkMapCache.getAnyNotary() ?: throw IllegalArgumentException("Couldn't find any notary in NetworkMapCache")
// invoke Cash subflow to issue Asset // invoke Cash subflow to issue Asset
progressTracker.currentStep = ISSUING progressTracker.currentStep = ISSUING
val issueCashFlow = CashIssueFlow(amount, issuerPartyRef, notaryParty) val issueCashFlow = CashIssueFlow(amount, issuerPartyRef, notaryParty)

View File

@ -10,7 +10,6 @@ import net.corda.core.flows.*
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.FetchDataFlow import net.corda.core.internal.FetchDataFlow
import net.corda.core.node.services.ServiceType
import net.corda.core.node.services.Vault.Page import net.corda.core.node.services.Vault.Page
import net.corda.core.node.services.queryBy import net.corda.core.node.services.queryBy
import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria
@ -40,7 +39,7 @@ object FlowCookbook {
@StartableByRPC @StartableByRPC
// Every flow must subclass ``FlowLogic``. The generic indicates the // Every flow must subclass ``FlowLogic``. The generic indicates the
// flow's return type. // flow's return type.
class InitiatorFlow(val arg1: Boolean, val arg2: Int, val counterparty: Party) : FlowLogic<Unit>() { class InitiatorFlow(val arg1: Boolean, val arg2: Int, val counterparty: Party, val regulator: Party) : FlowLogic<Unit>() {
/**--------------------------------- /**---------------------------------
* WIRING UP THE PROGRESS TRACKER * * WIRING UP THE PROGRESS TRACKER *
@ -109,22 +108,18 @@ object FlowCookbook {
// Unlike the first two methods, ``getNotaryNodes`` returns a // Unlike the first two methods, ``getNotaryNodes`` returns a
// ``List<NodeInfo>``. We have to extract the notary identity of // ``List<NodeInfo>``. We have to extract the notary identity of
// the node we want. // the node we want.
val firstNotary: Party = serviceHub.networkMapCache.notaryNodes[0].notaryIdentity val firstNotary: Party = serviceHub.networkMapCache.notaryIdentities[0].party
// DOCEND 1 // DOCEND 1
// We may also need to identify a specific counterparty. We // We may also need to identify a specific counterparty. We
// do so using identity service. // do so using identity service.
// DOCSTART 2 // DOCSTART 2
val namedCounterparty: Party? = serviceHub.identityService.partyFromX500Name(CordaX500Name(organisation = "NodeA", locality = "London", country = "UK")) val namedCounterparty: Party = serviceHub.identityService.partyFromX500Name(CordaX500Name(organisation = "NodeA", locality = "London", country = "UK")) ?:
val keyedCounterparty: Party? = serviceHub.identityService.partyFromKey(dummyPubKey) throw IllegalArgumentException("Couldn't find counterparty for NodeA in identity service")
val keyedCounterparty: Party = serviceHub.identityService.partyFromKey(dummyPubKey) ?:
throw IllegalArgumentException("Couldn't find counterparty with key: $dummyPubKey in identity service")
// DOCEND 2 // DOCEND 2
// Finally, we can use the map to identify nodes providing a
// specific service (e.g. a regulator or an oracle).
// DOCSTART 3
val regulator: Party = serviceHub.networkMapCache.getPeersWithService(ServiceType.regulator)[0].identity.party
// DOCEND 3
/**----------------------------- /**-----------------------------
* SENDING AND RECEIVING DATA * * SENDING AND RECEIVING DATA *
-----------------------------**/ -----------------------------**/

View File

@ -1,7 +1,7 @@
package net.corda.docs package net.corda.docs
import net.corda.core.contracts.Amount import net.corda.core.contracts.Amount
import net.corda.core.node.services.ServiceInfo import net.corda.core.identity.Party
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.finance.* import net.corda.finance.*
@ -9,11 +9,13 @@ import net.corda.finance.contracts.getCashBalances
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.finance.schemas.CashSchemaV1 import net.corda.finance.schemas.CashSchemaV1
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.network.NetworkMapService import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.DUMMY_NOTARY_KEY import net.corda.testing.DUMMY_NOTARY_KEY
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import org.junit.After import org.junit.After
import org.junit.Assert import org.junit.Assert
@ -27,6 +29,7 @@ class CustomVaultQueryTest {
lateinit var notaryNode: StartedNode<MockNetwork.MockNode> lateinit var notaryNode: StartedNode<MockNetwork.MockNode>
lateinit var nodeA: StartedNode<MockNetwork.MockNode> lateinit var nodeA: StartedNode<MockNetwork.MockNode>
lateinit var nodeB: StartedNode<MockNetwork.MockNode> lateinit var nodeB: StartedNode<MockNetwork.MockNode>
lateinit var notary: Party
@Before @Before
fun setup() { fun setup() {
@ -43,6 +46,7 @@ class CustomVaultQueryTest {
nodeA.internals.installCordaService(CustomVaultQuery.Service::class.java) nodeA.internals.installCordaService(CustomVaultQuery.Service::class.java)
nodeA.internals.registerCustomSchemas(setOf(CashSchemaV1)) nodeA.internals.registerCustomSchemas(setOf(CashSchemaV1))
nodeB.internals.registerCustomSchemas(setOf(CashSchemaV1)) nodeB.internals.registerCustomSchemas(setOf(CashSchemaV1))
notary = nodeA.services.getDefaultNotary()
} }
@After @After
@ -71,7 +75,7 @@ class CustomVaultQueryTest {
// Use NodeA as issuer and create some dollars // Use NodeA as issuer and create some dollars
val flowHandle1 = nodeA.services.startFlow(CashIssueFlow(amountToIssue, val flowHandle1 = nodeA.services.startFlow(CashIssueFlow(amountToIssue,
OpaqueBytes.of(0x01), OpaqueBytes.of(0x01),
notaryNode.info.notaryIdentity)) notary))
// Wait for the flow to stop and print // Wait for the flow to stop and print
flowHandle1.resultFuture.getOrThrow() flowHandle1.resultFuture.getOrThrow()
} }
@ -81,7 +85,7 @@ class CustomVaultQueryTest {
nodeA.info.chooseIdentity(), nodeA.info.chooseIdentity(),
OpaqueBytes.of(0x01), OpaqueBytes.of(0x01),
nodeA.info.chooseIdentity(), nodeA.info.chooseIdentity(),
notaryNode.info.notaryIdentity)) notary))
flowHandle1.resultFuture.getOrThrow() flowHandle1.resultFuture.getOrThrow()
} }

View File

@ -1,6 +1,6 @@
package net.corda.docs package net.corda.docs
import net.corda.core.node.services.ServiceInfo import net.corda.core.identity.Party
import net.corda.core.toFuture import net.corda.core.toFuture
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
@ -9,11 +9,13 @@ import net.corda.finance.contracts.getCashBalances
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.finance.schemas.CashSchemaV1 import net.corda.finance.schemas.CashSchemaV1
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.network.NetworkMapService import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.DUMMY_NOTARY_KEY import net.corda.testing.DUMMY_NOTARY_KEY
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
@ -25,6 +27,7 @@ class FxTransactionBuildTutorialTest {
lateinit var notaryNode: StartedNode<MockNetwork.MockNode> lateinit var notaryNode: StartedNode<MockNetwork.MockNode>
lateinit var nodeA: StartedNode<MockNetwork.MockNode> lateinit var nodeA: StartedNode<MockNetwork.MockNode>
lateinit var nodeB: StartedNode<MockNetwork.MockNode> lateinit var nodeB: StartedNode<MockNetwork.MockNode>
lateinit var notary: Party
@Before @Before
fun setup() { fun setup() {
@ -39,6 +42,7 @@ class FxTransactionBuildTutorialTest {
nodeA.internals.registerCustomSchemas(setOf(CashSchemaV1)) nodeA.internals.registerCustomSchemas(setOf(CashSchemaV1))
nodeB.internals.registerCustomSchemas(setOf(CashSchemaV1)) nodeB.internals.registerCustomSchemas(setOf(CashSchemaV1))
nodeB.internals.registerInitiatedFlow(ForeignExchangeRemoteFlow::class.java) nodeB.internals.registerInitiatedFlow(ForeignExchangeRemoteFlow::class.java)
notary = nodeA.services.getDefaultNotary()
} }
@After @After
@ -51,7 +55,7 @@ class FxTransactionBuildTutorialTest {
// Use NodeA as issuer and create some dollars // Use NodeA as issuer and create some dollars
val flowHandle1 = nodeA.services.startFlow(CashIssueFlow(DOLLARS(1000), val flowHandle1 = nodeA.services.startFlow(CashIssueFlow(DOLLARS(1000),
OpaqueBytes.of(0x01), OpaqueBytes.of(0x01),
notaryNode.info.notaryIdentity)) notary))
// Wait for the flow to stop and print // Wait for the flow to stop and print
flowHandle1.resultFuture.getOrThrow() flowHandle1.resultFuture.getOrThrow()
printBalances() printBalances()
@ -59,7 +63,7 @@ class FxTransactionBuildTutorialTest {
// Using NodeB as Issuer create some pounds. // Using NodeB as Issuer create some pounds.
val flowHandle2 = nodeB.services.startFlow(CashIssueFlow(POUNDS(1000), val flowHandle2 = nodeB.services.startFlow(CashIssueFlow(POUNDS(1000),
OpaqueBytes.of(0x01), OpaqueBytes.of(0x01),
notaryNode.info.notaryIdentity)) notary))
// Wait for flow to come to an end and print // Wait for flow to come to an end and print
flowHandle2.resultFuture.getOrThrow() flowHandle2.resultFuture.getOrThrow()
printBalances() printBalances()

View File

@ -4,12 +4,12 @@ import net.corda.core.contracts.LinearState
import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.UniqueIdentifier import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.queryBy import net.corda.core.node.services.queryBy
import net.corda.core.node.services.vault.QueryCriteria import net.corda.core.node.services.vault.QueryCriteria
import net.corda.core.toFuture import net.corda.core.toFuture
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.network.NetworkMapService import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY

View File

@ -331,7 +331,7 @@ the initiator then the buyer side would need to register their flow, perhaps wit
services.registerServiceFlow(TwoPartyTradeFlow.Seller::class.java) { services.registerServiceFlow(TwoPartyTradeFlow.Seller::class.java) {
TwoPartyTradeFlow.Buyer( TwoPartyTradeFlow.Buyer(
it, it,
notary = services.networkMapCache.notaryNodes[0].notaryIdentity, notary = services.networkMapCache.notaryIdentities[0].party,
acceptablePrice = TODO(), acceptablePrice = TODO(),
typeToBuy = TODO()) typeToBuy = TODO())
} }

View File

@ -31,8 +31,8 @@ with this basic skeleton:
val nodes = mockNet.createSomeNodes() val nodes = mockNet.createSomeNodes()
a = nodes.partyNodes[0] a = nodes.partyNodes[0]
b = nodes.partyNodes[1] b = nodes.partyNodes[1]
notary = nodes.notaryNode.info.notaryIdentity
mockNet.runNetwork() mockNet.runNetwork()
notary = a.services.getDefaultNotary()
} }
@After @After

View File

@ -11,8 +11,6 @@ import net.corda.core.flows.FlowLogic
import net.corda.core.flows.SignTransactionFlow import net.corda.core.flows.SignTransactionFlow
import net.corda.core.identity.AnonymousParty import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.node.NodeInfo
import net.corda.core.node.services.ServiceType
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
@ -51,7 +49,7 @@ object TwoPartyDealFlow {
} }
abstract val payload: Any abstract val payload: Any
abstract val notaryNode: NodeInfo abstract val notaryParty: Party
abstract val otherParty: Party abstract val otherParty: Party
@Suspendable override fun call(): SignedTransaction { @Suspendable override fun call(): SignedTransaction {
@ -82,7 +80,8 @@ object TwoPartyDealFlow {
/** /**
* Abstracted bilateral deal flow participant that is recipient of initial communication. * Abstracted bilateral deal flow participant that is recipient of initial communication.
*/ */
abstract class Secondary<U>(override val progressTracker: ProgressTracker = Secondary.tracker()) : FlowLogic<SignedTransaction>() { abstract class Secondary<U>(override val progressTracker: ProgressTracker = Secondary.tracker(),
val regulators: List<Party> = emptyList()) : FlowLogic<SignedTransaction>() {
companion object { companion object {
object RECEIVING : ProgressTracker.Step("Waiting for deal info.") object RECEIVING : ProgressTracker.Step("Waiting for deal info.")
@ -126,12 +125,10 @@ object TwoPartyDealFlow {
logger.trace { "Recorded transaction." } logger.trace { "Recorded transaction." }
progressTracker.currentStep = COPYING_TO_REGULATOR progressTracker.currentStep = COPYING_TO_REGULATOR
val regulators = serviceHub.networkMapCache.regulatorNodes
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, ftx) }
regulators.forEach { send(it.serviceIdentities(ServiceType.regulator).first(), ftx) }
}
progressTracker.currentStep = COPYING_TO_COUNTERPARTY progressTracker.currentStep = COPYING_TO_COUNTERPARTY
// Send the final transaction hash back to the other party. // Send the final transaction hash back to the other party.
@ -173,8 +170,7 @@ object TwoPartyDealFlow {
open class Instigator(override val otherParty: Party, open class Instigator(override val otherParty: Party,
override val payload: AutoOffer, override val payload: AutoOffer,
override val progressTracker: ProgressTracker = Primary.tracker()) : Primary() { override val progressTracker: ProgressTracker = Primary.tracker()) : Primary() {
override val notaryNode: NodeInfo get() = override val notaryParty: Party get() = payload.notary
serviceHub.networkMapCache.notaryNodes.single { it.notaryIdentity == payload.notary }
@Suspendable override fun checkProposal(stx: SignedTransaction) = requireThat { @Suspendable override fun checkProposal(stx: SignedTransaction) = requireThat {
// Add some constraints here. // Add some constraints here.

View File

@ -56,7 +56,6 @@ object TwoPartyTradeFlow {
) )
open class Seller(val otherParty: Party, open class Seller(val otherParty: Party,
val notaryNode: NodeInfo,
val assetToSell: StateAndRef<OwnableState>, val assetToSell: StateAndRef<OwnableState>,
val price: Amount<Currency>, val price: Amount<Currency>,
val myParty: PartyAndCertificate, // TODO Left because in tests it's used to pass anonymous party. val myParty: PartyAndCertificate, // TODO Left because in tests it's used to pass anonymous party.

View File

@ -8,6 +8,7 @@ import net.corda.finance.`issued by`
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.MockNode import net.corda.testing.node.MockNetwork.MockNode
@ -31,10 +32,10 @@ class CashExitFlowTests {
val nodes = mockNet.createSomeNodes(1) val nodes = mockNet.createSomeNodes(1)
notaryNode = nodes.notaryNode notaryNode = nodes.notaryNode
bankOfCordaNode = nodes.partyNodes[0] bankOfCordaNode = nodes.partyNodes[0]
notary = notaryNode.info.notaryIdentity
bankOfCorda = bankOfCordaNode.info.chooseIdentity() bankOfCorda = bankOfCordaNode.info.chooseIdentity()
mockNet.runNetwork() mockNet.runNetwork()
notary = bankOfCordaNode.services.getDefaultNotary()
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary)).resultFuture val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary)).resultFuture
mockNet.runNetwork() mockNet.runNetwork()
future.getOrThrow() future.getOrThrow()

View File

@ -8,6 +8,7 @@ import net.corda.finance.`issued by`
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.MockNode import net.corda.testing.node.MockNetwork.MockNode
@ -29,10 +30,10 @@ class CashIssueFlowTests {
val nodes = mockNet.createSomeNodes(1) val nodes = mockNet.createSomeNodes(1)
notaryNode = nodes.notaryNode notaryNode = nodes.notaryNode
bankOfCordaNode = nodes.partyNodes[0] bankOfCordaNode = nodes.partyNodes[0]
notary = notaryNode.info.notaryIdentity
bankOfCorda = bankOfCordaNode.info.chooseIdentity() bankOfCorda = bankOfCordaNode.info.chooseIdentity()
mockNet.runNetwork() mockNet.runNetwork()
notary = bankOfCordaNode.services.getDefaultNotary()
} }
@After @After

View File

@ -13,6 +13,7 @@ import net.corda.node.internal.StartedNode
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.expect import net.corda.testing.expect
import net.corda.testing.expectEvents import net.corda.testing.expectEvents
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.MockNode import net.corda.testing.node.MockNetwork.MockNode
@ -36,11 +37,11 @@ class CashPaymentFlowTests {
val nodes = mockNet.createSomeNodes(1) val nodes = mockNet.createSomeNodes(1)
notaryNode = nodes.notaryNode notaryNode = nodes.notaryNode
bankOfCordaNode = nodes.partyNodes[0] bankOfCordaNode = nodes.partyNodes[0]
notary = notaryNode.info.notaryIdentity
bankOfCorda = bankOfCordaNode.info.chooseIdentity() bankOfCorda = bankOfCordaNode.info.chooseIdentity()
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary)).resultFuture
mockNet.runNetwork() mockNet.runNetwork()
notary = bankOfCordaNode.services.getDefaultNotary()
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary)).resultFuture
future.getOrThrow() future.getOrThrow()
} }

View File

@ -1,4 +1,4 @@
package net.corda.core.node.services package net.corda.nodeapi
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable

View File

@ -1,4 +1,4 @@
package net.corda.core.node.services package net.corda.nodeapi
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
@ -27,15 +27,8 @@ class ServiceType private constructor(val id: String) {
} }
val notary: ServiceType = corda.getSubType("notary") val notary: ServiceType = corda.getSubType("notary")
val regulator: ServiceType = corda.getSubType("regulator")
val networkMap: ServiceType = corda.getSubType("network_map") val networkMap: ServiceType = corda.getSubType("network_map")
@JvmStatic
fun getServiceType(namespace: String, typeId: String): ServiceType {
require(!namespace.startsWith("corda")) { "Corda namespace is protected" }
return baseWithSubType(namespace, typeId)
}
fun parse(id: String): ServiceType = ServiceType(id) fun parse(id: String): ServiceType = ServiceType(id)
private fun baseWithSubType(baseId: String, subTypeId: String) = ServiceType("$baseId.$subTypeId") private fun baseWithSubType(baseId: String, subTypeId: String) = ServiceType("$baseId.$subTypeId")
@ -45,8 +38,6 @@ class ServiceType private constructor(val id: String) {
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) fun isNotary() = isSubTypeOf(notary)
fun isValidatingNotary() = isNotary() && id.contains(".validating")
fun isNetworkMap() = id == networkMap.id
override fun equals(other: Any?): Boolean = other === this || other is ServiceType && other.id == this.id override fun equals(other: Any?): Boolean = other === this || other is ServiceType && other.id == this.id
override fun hashCode(): Int = id.hashCode() override fun hashCode(): Int = id.hashCode()

View File

@ -5,12 +5,12 @@ import net.corda.core.internal.div
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StartableByRPC import net.corda.core.flows.StartableByRPC
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.ServiceType
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.testing.ALICE import net.corda.testing.ALICE
import net.corda.node.internal.NodeStartup import net.corda.node.internal.NodeStartup
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.nodeapi.ServiceType
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.driver.ListenProcessDeathException import net.corda.testing.driver.ListenProcessDeathException
import net.corda.testing.driver.NetworkMapStartStrategy import net.corda.testing.driver.NetworkMapStartStrategy
@ -18,6 +18,7 @@ import net.corda.testing.ProjectStructure.projectRootDir
import net.corda.testing.driver.driver import net.corda.testing.driver.driver
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Ignore
import org.junit.Test import org.junit.Test
import java.io.* import java.io.*
import java.nio.file.Files import java.nio.file.Files
@ -54,9 +55,10 @@ class BootTests {
} }
} }
@Ignore("Need rewriting to produce too big network map registration (adverticed services trick doesn't work after services removal).")
@Test @Test
fun `node quits on failure to register with network map`() { fun `node quits on failure to register with network map`() {
val tooManyAdvertisedServices = (1..100).map { ServiceInfo(ServiceType.regulator.getSubType("$it")) }.toSet() val tooManyAdvertisedServices = (1..100).map { ServiceInfo(ServiceType.notary.getSubType("$it")) }.toSet()
driver(networkMapStartStrategy = NetworkMapStartStrategy.Nominated(ALICE.name)) { driver(networkMapStartStrategy = NetworkMapStartStrategy.Nominated(ALICE.name)) {
val future = startNode(providedName = ALICE.name, advertisedServices = tooManyAdvertisedServices) val future = startNode(providedName = ALICE.name, advertisedServices = tooManyAdvertisedServices)
assertFailsWith(ListenProcessDeathException::class) { future.getOrThrow() } assertFailsWith(ListenProcessDeathException::class) { future.getOrThrow() }

View File

@ -6,13 +6,13 @@ import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StartableByRPC import net.corda.core.flows.StartableByRPC
import net.corda.core.internal.concurrent.transpose import net.corda.core.internal.concurrent.transpose
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.minutes import net.corda.core.utilities.minutes
import net.corda.finance.DOLLARS import net.corda.finance.DOLLARS
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
@ -110,9 +110,10 @@ class NodePerformanceTests {
a as NodeHandle.InProcess a as NodeHandle.InProcess
val metricRegistry = startReporter(shutdownManager, a.node.services.monitoringService.metrics) val metricRegistry = startReporter(shutdownManager, a.node.services.monitoringService.metrics)
a.rpcClientToNode().use("A", "A") { connection -> a.rpcClientToNode().use("A", "A") { connection ->
val notary = connection.proxy.notaryIdentities().first().party
println("ISSUING") println("ISSUING")
val doneFutures = (1..100).toList().parallelStream().map { val doneFutures = (1..100).toList().parallelStream().map {
connection.proxy.startFlow(::CashIssueFlow, 1.DOLLARS, OpaqueBytes.of(0), a.nodeInfo.notaryIdentity).returnValue connection.proxy.startFlow(::CashIssueFlow, 1.DOLLARS, OpaqueBytes.of(0), notary).returnValue
}.toList() }.toList()
doneFutures.transpose().get() doneFutures.transpose().get()
println("STARTING PAYMENT") println("STARTING PAYMENT")

View File

@ -1,42 +0,0 @@
package net.corda.node.services
import co.paralleluniverse.fibers.Suspendable
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.CordaX500Name
import net.corda.core.messaging.startFlow
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.ServiceType
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.User
import net.corda.testing.driver.driver
import org.junit.Test
import kotlin.test.assertTrue
class AdvertisedServiceTests {
private val serviceName = CordaX500Name(organisation = "Custom Service", locality = "London", country = "GB")
private val serviceType = ServiceType.corda.getSubType("custom")
private val user = "bankA"
private val pass = "passA"
@StartableByRPC
class ServiceTypeCheckingFlow : FlowLogic<Boolean>() {
@Suspendable
override fun call(): Boolean {
return serviceHub.networkMapCache.getAnyServiceOfType(ServiceType.corda.getSubType("custom")) != null
}
}
@Test
fun `service is accessible through getAnyServiceOfType`() {
driver(startNodesInProcess = true) {
val bankA = startNode(rpcUsers = listOf(User(user, pass, setOf(startFlowPermission<ServiceTypeCheckingFlow>())))).get()
startNode(providedName = serviceName, advertisedServices = setOf(ServiceInfo(serviceType))).get()
bankA.rpcClientToNode().use(user, pass) { connection ->
val result = connection.proxy.startFlow(::ServiceTypeCheckingFlow).returnValue.get()
assertTrue(result)
}
}
}
}

View File

@ -10,7 +10,6 @@ import net.corda.core.flows.NotaryFlow
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.node.services.ServiceInfo
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
@ -23,10 +22,12 @@ import net.corda.node.services.transactions.BFTNonValidatingNotaryService
import net.corda.node.services.transactions.minClusterSize import net.corda.node.services.transactions.minClusterSize
import net.corda.node.services.transactions.minCorrectReplicas import net.corda.node.services.transactions.minCorrectReplicas
import net.corda.node.utilities.ServiceIdentityGenerator import net.corda.node.utilities.ServiceIdentityGenerator
import net.corda.nodeapi.ServiceInfo
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.dummyCommand import net.corda.testing.dummyCommand
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import org.junit.After import org.junit.After
import org.junit.Test import org.junit.Test
@ -47,7 +48,7 @@ class BFTNotaryServiceTests {
mockNet.stopNodes() mockNet.stopNodes()
} }
private fun bftNotaryCluster(clusterSize: Int, exposeRaces: Boolean = false): Party { private fun bftNotaryCluster(clusterSize: Int, exposeRaces: Boolean = false) {
Files.deleteIfExists("config" / "currentView") // XXX: Make config object warn if this exists? Files.deleteIfExists("config" / "currentView") // XXX: Make config object warn if this exists?
val replicaIds = (0 until clusterSize) val replicaIds = (0 until clusterSize)
val party = ServiceIdentityGenerator.generateToDisk( val party = ServiceIdentityGenerator.generateToDisk(
@ -66,13 +67,14 @@ class BFTNotaryServiceTests {
whenever(it.notaryClusterAddresses).thenReturn(notaryClusterAddresses) whenever(it.notaryClusterAddresses).thenReturn(notaryClusterAddresses)
}) })
} }
return party mockNet.runNetwork() // Exchange initial network map registration messages.
} }
/** Failure mode is the redundant replica gets stuck in startup, so we can't dispose it cleanly at the end. */ /** Failure mode is the redundant replica gets stuck in startup, so we can't dispose it cleanly at the end. */
@Test @Test
fun `all replicas start even if there is a new consensus during startup`() { fun `all replicas start even if there is a new consensus during startup`() {
val notary = bftNotaryCluster(minClusterSize(1), true) // This true adds a sleep to expose the race. bftNotaryCluster(minClusterSize(1), true) // This true adds a sleep to expose the race.
val notary = node.services.getDefaultNotary()
val f = node.run { val f = node.run {
val trivialTx = signInitialTransaction(notary) { val trivialTx = signInitialTransaction(notary) {
addOutputState(DummyContract.SingleOwnerState(owner = info.chooseIdentity()), DUMMY_PROGRAM_ID) addOutputState(DummyContract.SingleOwnerState(owner = info.chooseIdentity()), DUMMY_PROGRAM_ID)
@ -96,7 +98,8 @@ class BFTNotaryServiceTests {
private fun detectDoubleSpend(faultyReplicas: Int) { private fun detectDoubleSpend(faultyReplicas: Int) {
val clusterSize = minClusterSize(faultyReplicas) val clusterSize = minClusterSize(faultyReplicas)
val notary = bftNotaryCluster(clusterSize) bftNotaryCluster(clusterSize)
val notary = node.services.getDefaultNotary()
node.run { node.run {
val issueTx = signInitialTransaction(notary) { val issueTx = signInitialTransaction(notary) {
addOutputState(DummyContract.SingleOwnerState(owner = info.chooseIdentity()), DUMMY_PROGRAM_ID) addOutputState(DummyContract.SingleOwnerState(owner = info.chooseIdentity()), DUMMY_PROGRAM_ID)

View File

@ -2,7 +2,6 @@ package net.corda.node.services
import net.corda.core.contracts.Amount import net.corda.core.contracts.Amount
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.bufferUntilSubscribed import net.corda.core.internal.bufferUntilSubscribed
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.StateMachineUpdate import net.corda.core.messaging.StateMachineUpdate
@ -51,14 +50,9 @@ class DistributedServiceTests : DriverBasedTest() {
raftNotaryIdentity = notaryIdentity raftNotaryIdentity = notaryIdentity
notaries = notaryNodes.map { it as NodeHandle.OutOfProcess } notaries = notaryNodes.map { it as NodeHandle.OutOfProcess }
val notariesIdentities = notaries.fold(HashSet<PartyAndCertificate>()) {
acc, elem -> acc.addAll(elem.nodeInfo.legalIdentitiesAndCerts)
acc
}
assertEquals(notaries.size, clusterSize) assertEquals(notaries.size, clusterSize)
// Check that each notary has different identity as a node. // Check that each notary has different identity as a node.
assertEquals(notaries.size, notariesIdentities.size - notaries[0].nodeInfo.advertisedServices.size) assertEquals(notaries.size, notaries.map { it.nodeInfo.chooseIdentity() }.toSet().size)
// Connect to Alice and the notaries // Connect to Alice and the notaries
fun connectRpc(node: NodeHandle): CordaRPCOps { fun connectRpc(node: NodeHandle): CordaRPCOps {
val client = node.rpcClientToNode() val client = node.rpcClientToNode()

View File

@ -8,7 +8,6 @@ import net.corda.core.internal.elapsedTime
import net.corda.core.internal.times import net.corda.core.internal.times
import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.MessageRecipients
import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.services.ServiceInfo
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
@ -19,6 +18,7 @@ import net.corda.node.services.messaging.*
import net.corda.node.services.transactions.RaftValidatingNotaryService import net.corda.node.services.transactions.RaftValidatingNotaryService
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.node.utilities.ServiceIdentityGenerator import net.corda.node.utilities.ServiceIdentityGenerator
import net.corda.nodeapi.ServiceInfo
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.node.NodeBasedTest import net.corda.testing.node.NodeBasedTest
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
@ -84,7 +84,8 @@ class P2PMessagingTest : NodeBasedTest() {
startNode(ALICE.name) startNode(ALICE.name)
).transpose().getOrThrow() ).transpose().getOrThrow()
assertAllNodesAreUsed(listOf(networkMapNode, serviceNode2), SERVICE_2_NAME.copy(commonName = "DistributedService"), alice) val serviceName = serviceNode2.info.legalIdentities[1].name
assertAllNodesAreUsed(listOf(networkMapNode, serviceNode2), serviceName, alice)
} }
@Ignore @Ignore

View File

@ -8,7 +8,6 @@ import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.node.services.ServiceInfo
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState import net.corda.core.schemas.PersistentState
import net.corda.core.schemas.QueryableState import net.corda.core.schemas.QueryableState
@ -19,6 +18,7 @@ import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.node.services.FlowPermissions import net.corda.node.services.FlowPermissions
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY

View File

@ -22,7 +22,6 @@ import net.corda.core.messaging.RPCOps
import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.CordaPluginRegistry import net.corda.core.node.CordaPluginRegistry
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.ServiceEntry
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import net.corda.core.node.services.* import net.corda.core.node.services.*
import net.corda.core.node.services.NetworkMapCache.MapChange import net.corda.core.node.services.NetworkMapCache.MapChange
@ -37,6 +36,8 @@ import net.corda.node.internal.cordapp.CordappLoader
import net.corda.node.internal.cordapp.CordappProvider import net.corda.node.internal.cordapp.CordappProvider
import net.corda.node.services.NotaryChangeHandler import net.corda.node.services.NotaryChangeHandler
import net.corda.node.services.NotifyTransactionHandler import net.corda.node.services.NotifyTransactionHandler
import net.corda.nodeapi.ServiceInfo
import net.corda.nodeapi.ServiceType
import net.corda.node.services.api.* import net.corda.node.services.api.*
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.configureWithDevSSLCertificate import net.corda.node.services.config.configureWithDevSSLCertificate
@ -75,6 +76,7 @@ import java.lang.reflect.InvocationTargetException
import java.nio.file.Path import java.nio.file.Path
import java.security.KeyPair import java.security.KeyPair
import java.security.KeyStoreException import java.security.KeyStoreException
import java.security.PublicKey
import java.security.cert.CertificateFactory import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate import java.security.cert.X509Certificate
import java.sql.Connection import java.sql.Connection
@ -134,8 +136,9 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
protected val services: ServiceHubInternal get() = _services protected val services: ServiceHubInternal get() = _services
private lateinit var _services: ServiceHubInternalImpl private lateinit var _services: ServiceHubInternalImpl
lateinit var legalIdentity: PartyAndCertificate protected lateinit var legalIdentity: PartyAndCertificate
protected lateinit var info: NodeInfo protected lateinit var info: NodeInfo
protected var myNotaryIdentity: PartyAndCertificate? = null
protected lateinit var checkpointStorage: CheckpointStorage protected lateinit var checkpointStorage: CheckpointStorage
protected lateinit var smm: StateMachineManager protected lateinit var smm: StateMachineManager
protected lateinit var attachments: NodeAttachmentService protected lateinit var attachments: NodeAttachmentService
@ -391,7 +394,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
services.auditService, services.monitoringService, services.networkMapCache, services.schemaService, services.auditService, services.monitoringService, services.networkMapCache, services.schemaService,
services.transactionVerifierService, services.validatedTransactions, services.contractUpgradeService, services.transactionVerifierService, services.validatedTransactions, services.contractUpgradeService,
services, this) services, this)
makeAdvertisedServices(tokenizableServices) makeNetworkServices(tokenizableServices)
return tokenizableServices return tokenizableServices
} }
@ -414,22 +417,21 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
} }
private fun makeInfo(legalIdentity: PartyAndCertificate): NodeInfo { private fun makeInfo(legalIdentity: PartyAndCertificate): NodeInfo {
val advertisedServiceEntries = makeServiceEntries() // TODO We keep only notary identity as additional legalIdentity if we run it on a node . Multiple identities need more design thinking.
myNotaryIdentity = getNotaryIdentity()
val allIdentitiesList = mutableListOf(legalIdentity) val allIdentitiesList = mutableListOf(legalIdentity)
allIdentitiesList.addAll(advertisedServiceEntries.map { it.identity }) // TODO Will we keep service identities here, for example notaries? myNotaryIdentity?.let { allIdentitiesList.add(it) }
val addresses = myAddresses() // TODO There is no support for multiple IP addresses yet. val addresses = myAddresses() // TODO There is no support for multiple IP addresses yet.
return NodeInfo(addresses, allIdentitiesList, platformVersion, advertisedServiceEntries, platformClock.instant().toEpochMilli()) return NodeInfo(addresses, allIdentitiesList, platformVersion, platformClock.instant().toEpochMilli())
} }
/** /**
* A service entry contains the advertised [ServiceInfo] along with the service identity. The identity *name* is * A service entry contains the advertised [ServiceInfo] along with the service identity. The identity *name* is
* taken from the configuration or, if non specified, generated by combining the node's legal name and the service id. * taken from the configuration or, if non specified, generated by combining the node's legal name and the service id.
* Used only for notary identities.
*/ */
protected open fun makeServiceEntries(): List<ServiceEntry> { protected open fun getNotaryIdentity(): PartyAndCertificate? {
return advertisedServices.map { return advertisedServices.singleOrNull { it.type.isNotary() }?.let { obtainIdentity(it) }
val identity = obtainIdentity(it)
ServiceEntry(it, identity)
}
} }
@VisibleForTesting @VisibleForTesting
@ -478,8 +480,8 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
} }
} }
private fun makeAdvertisedServices(tokenizableServices: MutableList<Any>) { private fun makeNetworkServices(tokenizableServices: MutableList<Any>) {
val serviceTypes = info.advertisedServices.map { it.info.type } val serviceTypes = advertisedServices.map { it.type }
inNodeNetworkMapService = if (NetworkMapService.type in serviceTypes) makeNetworkMapService() else NullNetworkMapService inNodeNetworkMapService = if (NetworkMapService.type in serviceTypes) makeNetworkMapService() else NullNetworkMapService
val notaryServiceType = serviceTypes.singleOrNull { it.isNotary() } val notaryServiceType = serviceTypes.singleOrNull { it.isNotary() }
if (notaryServiceType != null) { if (notaryServiceType != null) {
@ -584,7 +586,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
.filterNotNull() .filterNotNull()
.toTypedArray() .toTypedArray()
val service = PersistentIdentityService(info.legalIdentitiesAndCerts, trustRoot = trustRoot, caCertificates = *caCertificates) val service = PersistentIdentityService(info.legalIdentitiesAndCerts, trustRoot = trustRoot, caCertificates = *caCertificates)
services.networkMapCache.partyNodes.forEach { it.legalIdentitiesAndCerts.forEach { service.verifyAndRegisterIdentity(it) } } services.networkMapCache.allNodes.forEach { it.legalIdentitiesAndCerts.forEach { service.verifyAndRegisterIdentity(it) } }
services.networkMapCache.changed.subscribe { mapChange -> services.networkMapCache.changed.subscribe { mapChange ->
// TODO how should we handle network map removal // TODO how should we handle network map removal
if (mapChange is MapChange.Added) { if (mapChange is MapChange.Added) {
@ -628,7 +630,12 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
// Create node identity if service info = null // Create node identity if service info = null
Pair("identity", myLegalName.copy(commonName = null)) Pair("identity", myLegalName.copy(commonName = null))
} else { } else {
val name = serviceInfo.name ?: myLegalName.copy(commonName = serviceInfo.type.id) // Ensure that we always have notary in name and type of it. TODO It is temporary solution until we will have proper handling of NetworkParameters
val baseName = serviceInfo.name ?: myLegalName
val name = if (baseName.commonName == null)
baseName.copy(commonName = serviceInfo.type.id)
else
baseName.copy(commonName = baseName.commonName + " " + serviceInfo.type.id)
Pair(serviceInfo.type.id, name) Pair(serviceInfo.type.id, name)
} }
@ -728,6 +735,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
override val myInfo: NodeInfo get() = info override val myInfo: NodeInfo get() = info
override val database: CordaPersistence get() = this@AbstractNode.database override val database: CordaPersistence get() = this@AbstractNode.database
override val configuration: NodeConfiguration get() = this@AbstractNode.configuration override val configuration: NodeConfiguration get() = this@AbstractNode.configuration
override val notaryIdentityKey: PublicKey get() = myNotaryIdentity?.owningKey ?: throw IllegalArgumentException("Node doesn't have notary identity key")
override fun <T : SerializeAsToken> cordaService(type: Class<T>): T { override fun <T : SerializeAsToken> cordaService(type: Class<T>): T {
require(type.isAnnotationPresent(CordaService::class.java)) { "${type.name} is not a Corda service" } require(type.isAnnotationPresent(CordaService::class.java)) { "${type.name} is not a Corda service" }

View File

@ -10,6 +10,7 @@ import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.messaging.* import net.corda.core.messaging.*
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.NetworkMapCache
@ -114,6 +115,10 @@ class CordaRPCOpsImpl(
return services.myInfo return services.myInfo
} }
override fun notaryIdentities(): List<PartyAndCertificate> {
return services.networkMapCache.notaryIdentities
}
override fun addVaultTransactionNote(txnId: SecureHash, txnNote: String) { override fun addVaultTransactionNote(txnId: SecureHash, txnNote: String) {
return database.transaction { return database.transaction {
services.vaultService.addNoteToTransaction(txnId, txnNote) services.vaultService.addNoteToTransaction(txnId, txnNote)
@ -202,7 +207,7 @@ class CordaRPCOpsImpl(
} }
} }
override fun nodeIdentityFromParty(party: AbstractParty): NodeInfo? { override fun nodeInfoFromParty(party: AbstractParty): NodeInfo? {
return database.transaction { return database.transaction {
services.networkMapCache.getNodeByLegalIdentity(party) services.networkMapCache.getNodeByLegalIdentity(party)
} }

View File

@ -11,7 +11,6 @@ import net.corda.core.internal.concurrent.thenMatch
import net.corda.core.internal.uncheckedCast import net.corda.core.internal.uncheckedCast
import net.corda.core.messaging.RPCOps import net.corda.core.messaging.RPCOps
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import net.corda.core.node.services.ServiceInfo
import net.corda.core.serialization.SerializationDefaults import net.corda.core.serialization.SerializationDefaults
import net.corda.core.utilities.* import net.corda.core.utilities.*
import net.corda.node.VersionInfo import net.corda.node.VersionInfo
@ -19,6 +18,7 @@ import net.corda.node.serialization.KryoServerSerializationScheme
import net.corda.node.serialization.NodeClock import net.corda.node.serialization.NodeClock
import net.corda.node.services.RPCUserService import net.corda.node.services.RPCUserService
import net.corda.node.services.RPCUserServiceImpl import net.corda.node.services.RPCUserServiceImpl
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.config.FullNodeConfiguration import net.corda.node.services.config.FullNodeConfiguration
import net.corda.node.services.messaging.ArtemisMessagingServer import net.corda.node.services.messaging.ArtemisMessagingServer
import net.corda.node.services.messaging.ArtemisMessagingServer.Companion.ipDetectRequestProperty import net.corda.node.services.messaging.ArtemisMessagingServer.Companion.ipDetectRequestProperty

View File

@ -5,9 +5,9 @@ import com.typesafe.config.ConfigException
import joptsimple.OptionException import joptsimple.OptionException
import net.corda.core.internal.* import net.corda.core.internal.*
import net.corda.core.internal.concurrent.thenMatch import net.corda.core.internal.concurrent.thenMatch
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.loggerFor
import net.corda.node.* import net.corda.node.*
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.config.FullNodeConfiguration import net.corda.node.services.config.FullNodeConfiguration
import net.corda.node.services.transactions.bftSMaRtSerialFilter import net.corda.node.services.transactions.bftSMaRtSerialFilter
import net.corda.node.shell.InteractiveShell import net.corda.node.shell.InteractiveShell

View File

@ -8,13 +8,10 @@ import net.corda.core.flows.FlowLogic
import net.corda.core.flows.InitiatedBy import net.corda.core.flows.InitiatedBy
import net.corda.core.flows.StartableByRPC import net.corda.core.flows.StartableByRPC
import net.corda.core.internal.* import net.corda.core.internal.*
import net.corda.core.node.NodeInfo
import net.corda.core.node.CordaPluginRegistry import net.corda.core.node.CordaPluginRegistry
import net.corda.core.node.services.CordaService import net.corda.core.node.services.CordaService
import net.corda.core.node.services.ServiceType
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import net.corda.core.serialization.SerializeAsToken import net.corda.core.serialization.SerializeAsToken
import net.corda.core.utilities.debug
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.loggerFor
import net.corda.node.internal.classloading.requireAnnotation import net.corda.node.internal.classloading.requireAnnotation
import java.lang.reflect.Modifier import java.lang.reflect.Modifier
@ -23,9 +20,7 @@ import java.net.URI
import java.net.URL import java.net.URL
import java.net.URLClassLoader import java.net.URLClassLoader
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths
import java.util.* import java.util.*
import java.util.stream.Collectors
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.streams.toList import kotlin.streams.toList

View File

@ -38,7 +38,7 @@ class NotaryChangeHandler(otherSide: Party) : AbstractStateReplacementFlow.Accep
} }
// TODO: load and compare against notary whitelist from config. Remove the check below // TODO: load and compare against notary whitelist from config. Remove the check below
val isNotary = serviceHub.networkMapCache.notaryNodes.any { it.notaryIdentity == newNotary } val isNotary = serviceHub.networkMapCache.isNotary(newNotary)
if (!isNotary) { if (!isNotary) {
throw StateReplacementException("The proposed node $newNotary does not run a Notary service") throw StateReplacementException("The proposed node $newNotary does not run a Notary service")
} }

View File

@ -1,12 +0,0 @@
package net.corda.node.services.api
import net.corda.core.node.services.ServiceType
/**
* Placeholder interface for regulator services.
*/
interface RegulatorService {
companion object {
val type = ServiceType.regulator
}
}

View File

@ -1,9 +1,9 @@
package net.corda.node.services.config package net.corda.node.services.config
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.node.internal.NetworkMapInfo import net.corda.node.internal.NetworkMapInfo
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.messaging.CertificateChainCheckPolicy import net.corda.node.services.messaging.CertificateChainCheckPolicy
import net.corda.node.services.network.NetworkMapService import net.corda.node.services.network.NetworkMapService
import net.corda.nodeapi.User import net.corda.nodeapi.User

View File

@ -12,17 +12,16 @@ import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.services.KeyManagementService import net.corda.core.node.services.KeyManagementService
import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.NetworkMapCache
import net.corda.core.node.services.ServiceType
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.SerializedBytes
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.utilities.debug import net.corda.core.utilities.debug
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.loggerFor
import net.corda.nodeapi.ServiceType
import net.corda.node.services.api.AbstractNodeService import net.corda.node.services.api.AbstractNodeService
import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.messaging.MessageHandlerRegistration import net.corda.node.services.messaging.MessageHandlerRegistration
import net.corda.node.services.messaging.MessagingService
import net.corda.node.services.messaging.ServiceRequestMessage import net.corda.node.services.messaging.ServiceRequestMessage
import net.corda.node.services.messaging.createMessage import net.corda.node.services.messaging.createMessage
import net.corda.node.services.network.NetworkMapService.* import net.corda.node.services.network.NetworkMapService.*

View File

@ -4,6 +4,7 @@ import net.corda.core.concurrent.CordaFuture
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.VisibleForTesting import net.corda.core.internal.VisibleForTesting
import net.corda.core.internal.bufferUntilSubscribed import net.corda.core.internal.bufferUntilSubscribed
import net.corda.core.internal.concurrent.map import net.corda.core.internal.concurrent.map
@ -58,8 +59,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
// TODO Small explanation, partyNodes and registeredNodes is left in memory as it was before, because it will be removed in // TODO Small explanation, partyNodes and registeredNodes is left in memory as it was before, because it will be removed in
// next PR that gets rid of services. These maps are used only for queries by service. // next PR that gets rid of services. These maps are used only for queries by service.
protected val registeredNodes: MutableMap<PublicKey, NodeInfo> = Collections.synchronizedMap(HashMap()) protected val registeredNodes: MutableMap<PublicKey, NodeInfo> = Collections.synchronizedMap(HashMap())
override val partyNodes: MutableList<NodeInfo> get() = registeredNodes.map { it.value }.toMutableList() protected val partyNodes: MutableList<NodeInfo> get() = registeredNodes.map { it.value }.toMutableList()
override val networkMapNodes: List<NodeInfo> get() = getNodesWithService(NetworkMapService.type)
private val _changed = PublishSubject.create<MapChange>() private val _changed = PublishSubject.create<MapChange>()
// We use assignment here so that multiple subscribers share the same wrapped Observable. // We use assignment here so that multiple subscribers share the same wrapped Observable.
override val changed: Observable<MapChange> = _changed.wrapWithDatabaseTransaction() override val changed: Observable<MapChange> = _changed.wrapWithDatabaseTransaction()
@ -69,6 +69,15 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
override val nodeReady: CordaFuture<Void?> get() = _registrationFuture override val nodeReady: CordaFuture<Void?> get() = _registrationFuture
private var _loadDBSuccess: Boolean = false private var _loadDBSuccess: Boolean = false
override val loadDBSuccess get() = _loadDBSuccess override val loadDBSuccess get() = _loadDBSuccess
// TODO From the NetworkMapService redesign doc: Remove the concept of network services.
// As a temporary hack, just assume for now that every network has a notary service named "Notary Service" that can be looked up in the map.
// This should eliminate the only required usage of services.
// It is ensured on node startup when constructing a notary that the name contains "notary".
override val notaryIdentities: List<PartyAndCertificate> get() {
return partyNodes.flatMap { it.legalIdentitiesAndCerts }.filter {
it.name.toString().contains("corda.notary", true)
}.distinct().sortedBy { it.name.toString() } // Distinct, because of distributed service nodes.
}
init { init {
serviceHub.database.transaction { loadFromDB() } serviceHub.database.transaction { loadFromDB() }
@ -80,8 +89,8 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
return PartyInfo.SingleNode(party, nodes[0].addresses) return PartyInfo.SingleNode(party, nodes[0].addresses)
} }
for (node in nodes) { for (node in nodes) {
for (service in node.advertisedServices) { for (identity in node.legalIdentities) {
if (service.identity.party == party) { if (identity == party) {
return PartyInfo.DistributedNode(party) return PartyInfo.DistributedNode(party)
} }
} }
@ -89,9 +98,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
return null return null
} }
// TODO See comment to queryByLegalName why it's left like that. override fun getNodeByLegalName(name: CordaX500Name): NodeInfo? = serviceHub.database.transaction { queryByLegalName(name).firstOrNull() }
override fun getNodeByLegalName(principal: CordaX500Name): NodeInfo? = partyNodes.singleOrNull { principal in it.legalIdentities.map { it.name } }
//serviceHub!!.database.transaction { queryByLegalName(principal).firstOrNull() }
override fun getNodesByLegalIdentityKey(identityKey: PublicKey): List<NodeInfo> = override fun getNodesByLegalIdentityKey(identityKey: PublicKey): List<NodeInfo> =
serviceHub.database.transaction { queryByIdentityKey(identityKey) } serviceHub.database.transaction { queryByIdentityKey(identityKey) }
override fun getNodeByLegalIdentity(party: AbstractParty): NodeInfo? { override fun getNodeByLegalIdentity(party: AbstractParty): NodeInfo? {
@ -194,6 +201,12 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
} }
} }
override val allNodes: List<NodeInfo> get () = serviceHub.database.transaction {
createSession {
getAllInfos(it).map { it.toNodeInfo() }
}
}
private fun processRegistration(reg: NodeRegistration) { private fun processRegistration(reg: NodeRegistration) {
// TODO: Implement filtering by sequence number, so we only accept changes that are // TODO: Implement filtering by sequence number, so we only accept changes that are
// more recent than the latest change we've processed. // more recent than the latest change we've processed.
@ -251,8 +264,8 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
// network map registration on network map node) // network map registration on network map node)
serviceHub.database.dataSource.connection.use { serviceHub.database.dataSource.connection.use {
val session = serviceHub.database.entityManagerFactory.withOptions().connection(it.apply { val session = serviceHub.database.entityManagerFactory.withOptions().connection(it.apply {
transactionIsolation = 1 transactionIsolation = 1
}).openSession() }).openSession()
session.use { session.use {
val tx = session.beginTransaction() val tx = session.beginTransaction()
// TODO For now the main legal identity is left in NodeInfo, this should be set comparision/come up with index for NodeInfo? // TODO For now the main legal identity is left in NodeInfo, this should be set comparision/come up with index for NodeInfo?
@ -322,7 +335,6 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
legalIdentitiesAndCerts = nodeInfo.legalIdentitiesAndCerts.mapIndexed { idx, elem -> legalIdentitiesAndCerts = nodeInfo.legalIdentitiesAndCerts.mapIndexed { idx, elem ->
NodeInfoSchemaV1.DBPartyAndCertificate(elem, isMain = idx == 0) }, NodeInfoSchemaV1.DBPartyAndCertificate(elem, isMain = idx == 0) },
platformVersion = nodeInfo.platformVersion, platformVersion = nodeInfo.platformVersion,
advertisedServices = nodeInfo.advertisedServices.map { NodeInfoSchemaV1.DBServiceEntry(it.serialize().bytes) },
serial = nodeInfo.serial serial = nodeInfo.serial
) )
} }

View File

@ -2,9 +2,9 @@ package net.corda.node.services.transactions
import net.corda.core.flows.NotaryFlow import net.corda.core.flows.NotaryFlow
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.node.services.ServiceType
import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TimeWindowChecker
import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.core.node.services.TrustedAuthorityNotaryService
import net.corda.nodeapi.ServiceType
import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.api.ServiceHubInternal
/** A simple Notary service that does not perform transaction validation */ /** A simple Notary service that does not perform transaction validation */

View File

@ -38,7 +38,7 @@ class ValidatingNotaryFlow(otherSide: Party, service: TrustedAuthorityNotaryServ
private fun checkSignatures(stx: SignedTransaction) { private fun checkSignatures(stx: SignedTransaction) {
try { try {
stx.verifySignaturesExcept(serviceHub.myInfo.notaryIdentity.owningKey) stx.verifySignaturesExcept(serviceHub.notaryIdentityKey)
} catch(e: SignatureException) { } catch(e: SignatureException) {
throw NotaryException(NotaryError.TransactionInvalid(e)) throw NotaryException(NotaryError.TransactionInvalid(e))
} }

View File

@ -2,9 +2,9 @@ package net.corda.node.services.transactions
import net.corda.core.flows.NotaryFlow import net.corda.core.flows.NotaryFlow
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.node.services.ServiceType
import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TimeWindowChecker
import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.core.node.services.TrustedAuthorityNotaryService
import net.corda.nodeapi.ServiceType
import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.api.ServiceHubInternal
/** A Notary service that validates the transaction chain of the submitted transaction before committing it */ /** A Notary service that validates the transaction chain of the submitted transaction before committing it */

View File

@ -9,8 +9,8 @@ import net.corda.core.crypto.keys
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StartableByRPC import net.corda.core.flows.StartableByRPC
import net.corda.core.flows.StateMachineRunId import net.corda.core.flows.StateMachineRunId
import net.corda.core.identity.Party
import net.corda.core.messaging.* import net.corda.core.messaging.*
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
import net.corda.core.node.services.queryBy import net.corda.core.node.services.queryBy
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
@ -28,6 +28,7 @@ import net.corda.node.services.messaging.CURRENT_RPC_CONTEXT
import net.corda.node.services.messaging.RpcContext import net.corda.node.services.messaging.RpcContext
import net.corda.node.services.network.NetworkMapService import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.PermissionException import net.corda.nodeapi.PermissionException
import net.corda.nodeapi.User import net.corda.nodeapi.User
@ -59,6 +60,7 @@ class CordaRPCOpsImplTest {
lateinit var mockNet: MockNetwork lateinit var mockNet: MockNetwork
lateinit var aliceNode: StartedNode<MockNode> lateinit var aliceNode: StartedNode<MockNode>
lateinit var notaryNode: StartedNode<MockNode> lateinit var notaryNode: StartedNode<MockNode>
lateinit var notary: Party
lateinit var rpc: CordaRPCOps lateinit var rpc: CordaRPCOps
lateinit var stateMachineUpdates: Observable<StateMachineUpdate> lateinit var stateMachineUpdates: Observable<StateMachineUpdate>
lateinit var transactions: Observable<SignedTransaction> lateinit var transactions: Observable<SignedTransaction>
@ -78,6 +80,7 @@ class CordaRPCOpsImplTest {
mockNet.runNetwork() mockNet.runNetwork()
networkMap.internals.ensureRegistered() networkMap.internals.ensureRegistered()
notary = rpc.notaryIdentities().first().party
} }
@After @After
@ -102,7 +105,7 @@ class CordaRPCOpsImplTest {
// Tell the monitoring service node to issue some cash // Tell the monitoring service node to issue some cash
val recipient = aliceNode.info.chooseIdentity() val recipient = aliceNode.info.chooseIdentity()
val result = rpc.startFlow(::CashIssueFlow, Amount(quantity, GBP), ref, notaryNode.info.notaryIdentity) val result = rpc.startFlow(::CashIssueFlow, Amount(quantity, GBP), ref, notary)
mockNet.runNetwork() mockNet.runNetwork()
var issueSmId: StateMachineRunId? = null var issueSmId: StateMachineRunId? = null
@ -146,7 +149,7 @@ class CordaRPCOpsImplTest {
val result = rpc.startFlow(::CashIssueFlow, val result = rpc.startFlow(::CashIssueFlow,
100.DOLLARS, 100.DOLLARS,
OpaqueBytes(ByteArray(1, { 1 })), OpaqueBytes(ByteArray(1, { 1 })),
notaryNode.info.notaryIdentity notary
) )
mockNet.runNetwork() mockNet.runNetwork()
@ -196,7 +199,7 @@ class CordaRPCOpsImplTest {
val signaturePubKeys = stx.sigs.map { it.by }.toSet() val signaturePubKeys = stx.sigs.map { it.by }.toSet()
// Alice and Notary signed // Alice and Notary signed
require(aliceNode.services.keyManagementService.filterMyKeys(signaturePubKeys).toList().isNotEmpty()) require(aliceNode.services.keyManagementService.filterMyKeys(signaturePubKeys).toList().isNotEmpty())
require(notaryNode.info.notaryIdentity.owningKey.isFulfilledBy(signaturePubKeys)) require(notary.owningKey.isFulfilledBy(signaturePubKeys))
} }
) )
} }
@ -221,7 +224,7 @@ class CordaRPCOpsImplTest {
fun `cash command by user not permissioned for cash`() { fun `cash command by user not permissioned for cash`() {
CURRENT_RPC_CONTEXT.set(RpcContext(User("user", "pwd", permissions = emptySet()))) CURRENT_RPC_CONTEXT.set(RpcContext(User("user", "pwd", permissions = emptySet())))
assertThatExceptionOfType(PermissionException::class.java).isThrownBy { assertThatExceptionOfType(PermissionException::class.java).isThrownBy {
rpc.startFlow(::CashIssueFlow, Amount(100, USD), OpaqueBytes(ByteArray(1, { 1 })), notaryNode.info.notaryIdentity) rpc.startFlow(::CashIssueFlow, Amount(100, USD), OpaqueBytes(ByteArray(1, { 1 })), notary)
} }
} }

View File

@ -1,6 +1,6 @@
package net.corda.node.messaging package net.corda.node.messaging
import net.corda.core.node.services.ServiceInfo import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.messaging.Message import net.corda.node.services.messaging.Message
import net.corda.node.services.messaging.TopicStringValidator import net.corda.node.services.messaging.TopicStringValidator
import net.corda.node.services.messaging.createMessage import net.corda.node.services.messaging.createMessage

View File

@ -18,8 +18,6 @@ import net.corda.core.internal.rootCause
import net.corda.core.messaging.DataFeed import net.corda.core.messaging.DataFeed
import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.messaging.StateMachineTransactionMapping import net.corda.core.messaging.StateMachineTransactionMapping
import net.corda.core.node.NodeInfo
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
@ -38,6 +36,7 @@ import net.corda.finance.contracts.asset.*
import net.corda.finance.flows.TwoPartyTradeFlow.Buyer import net.corda.finance.flows.TwoPartyTradeFlow.Buyer
import net.corda.finance.flows.TwoPartyTradeFlow.Seller import net.corda.finance.flows.TwoPartyTradeFlow.Seller
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.api.WritableTransactionStorage import net.corda.node.services.api.WritableTransactionStorage
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.persistence.DBTransactionStorage import net.corda.node.services.persistence.DBTransactionStorage
@ -99,23 +98,25 @@ class TwoPartyTradeFlowTests {
val bankNode = basketOfNodes.partyNodes[2] val bankNode = basketOfNodes.partyNodes[2]
val cashIssuer = bankNode.info.chooseIdentity().ref(1) val cashIssuer = bankNode.info.chooseIdentity().ref(1)
val cpIssuer = bankNode.info.chooseIdentity().ref(1, 2, 3) val cpIssuer = bankNode.info.chooseIdentity().ref(1, 2, 3)
val notary = aliceNode.services.getDefaultNotary()
aliceNode.internals.disableDBCloseOnStop() aliceNode.internals.disableDBCloseOnStop()
bobNode.internals.disableDBCloseOnStop() bobNode.internals.disableDBCloseOnStop()
bobNode.database.transaction { bobNode.database.transaction {
bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, outputNotary = notaryNode.info.notaryIdentity, bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, outputNotary = notary,
issuedBy = cashIssuer) issuedBy = cashIssuer)
} }
val alicesFakePaper = aliceNode.database.transaction { val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, cpIssuer, aliceNode.info.chooseIdentity(), fillUpForSeller(false, cpIssuer, aliceNode.info.chooseIdentity(),
1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), null, notaryNode.info.notaryIdentity).second 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), null, notary).second
} }
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode) insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notaryNode, aliceNode, bobNode, val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, aliceNode, bobNode,
"alice's paper".outputStateAndRef()) "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.
@ -146,18 +147,19 @@ class TwoPartyTradeFlowTests {
val bobNode = mockNet.createPartyNode(notaryNode.network.myAddress, BOB.name) val bobNode = mockNet.createPartyNode(notaryNode.network.myAddress, BOB.name)
val bankNode = mockNet.createPartyNode(notaryNode.network.myAddress, BOC.name) val bankNode = mockNet.createPartyNode(notaryNode.network.myAddress, BOC.name)
val issuer = bankNode.info.chooseIdentity().ref(1) val issuer = bankNode.info.chooseIdentity().ref(1)
val notary = aliceNode.services.getDefaultNotary()
aliceNode.internals.disableDBCloseOnStop() aliceNode.internals.disableDBCloseOnStop()
bobNode.internals.disableDBCloseOnStop() bobNode.internals.disableDBCloseOnStop()
val cashStates = bobNode.database.transaction { val cashStates = bobNode.database.transaction {
bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, notaryNode.info.notaryIdentity, 3, 3, bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, notary, 3, 3,
issuedBy = issuer) issuedBy = issuer)
} }
val alicesFakePaper = aliceNode.database.transaction { val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(), fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(),
1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), null, notaryNode.info.notaryIdentity).second 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), null, notary).second
} }
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode) insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
@ -171,7 +173,7 @@ class TwoPartyTradeFlowTests {
} }
} }
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notaryNode, aliceNode, bobNode, val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, aliceNode, bobNode,
"alice's paper".outputStateAndRef()) "alice's paper".outputStateAndRef())
assertEquals(aliceResult.getOrThrow(), bobStateMachine.getOrThrow().resultFuture.getOrThrow()) assertEquals(aliceResult.getOrThrow(), bobStateMachine.getOrThrow().resultFuture.getOrThrow())
@ -216,17 +218,18 @@ class TwoPartyTradeFlowTests {
val networkMapAddress = notaryNode.network.myAddress val networkMapAddress = notaryNode.network.myAddress
mockNet.runNetwork() // Clear network map registration messages mockNet.runNetwork() // Clear network map registration messages
val notary = aliceNode.services.getDefaultNotary()
bobNode.database.transaction { bobNode.database.transaction {
bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, outputNotary = notaryNode.info.notaryIdentity, bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, outputNotary = notary,
issuedBy = issuer) issuedBy = issuer)
} }
val alicesFakePaper = aliceNode.database.transaction { val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(), fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(),
1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), null, notaryNode.info.notaryIdentity).second 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), null, notary).second
} }
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode) insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
val aliceFuture = runBuyerAndSeller(notaryNode, aliceNode, bobNode, "alice's paper".outputStateAndRef()).sellerResult val aliceFuture = runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef()).sellerResult
// Everything is on this thread so we can now step through the flow one step at a time. // Everything is on this thread so we can now step through the flow one step at a time.
// Seller Alice already sent a message to Buyer Bob. Pump once: // Seller Alice already sent a message to Buyer Bob. Pump once:
@ -332,9 +335,9 @@ class TwoPartyTradeFlowTests {
val bobNode = makeNodeWithTracking(notaryNode.network.myAddress, BOB.name) val bobNode = makeNodeWithTracking(notaryNode.network.myAddress, BOB.name)
val bankNode = makeNodeWithTracking(notaryNode.network.myAddress, BOC.name) val bankNode = makeNodeWithTracking(notaryNode.network.myAddress, BOC.name)
val issuer = bankNode.info.chooseIdentity().ref(1, 2, 3) val issuer = bankNode.info.chooseIdentity().ref(1, 2, 3)
mockNet.runNetwork() mockNet.runNetwork()
notaryNode.internals.ensureRegistered() notaryNode.internals.ensureRegistered()
val notary = aliceNode.services.getDefaultNotary()
mockNet.registerIdentities() mockNet.registerIdentities()
@ -352,17 +355,17 @@ class TwoPartyTradeFlowTests {
} }
val bobsFakeCash = fillUpForBuyer(false, issuer, AnonymousParty(bobNode.info.chooseIdentity().owningKey), val bobsFakeCash = fillUpForBuyer(false, issuer, AnonymousParty(bobNode.info.chooseIdentity().owningKey),
notaryNode.info.notaryIdentity).second notary).second
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bankNode) val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bankNode)
val alicesFakePaper = aliceNode.database.transaction { val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(), fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(),
1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), attachmentID, notaryNode.info.notaryIdentity).second 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), attachmentID, notary).second
} }
val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode) val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
mockNet.runNetwork() // Clear network map registration messages mockNet.runNetwork() // Clear network map registration messages
runBuyerAndSeller(notaryNode, aliceNode, bobNode, "alice's paper".outputStateAndRef()) runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef())
mockNet.runNetwork() mockNet.runNetwork()
@ -441,6 +444,7 @@ class TwoPartyTradeFlowTests {
mockNet.runNetwork() mockNet.runNetwork()
notaryNode.internals.ensureRegistered() notaryNode.internals.ensureRegistered()
val notary = aliceNode.services.getDefaultNotary()
mockNet.registerIdentities() mockNet.registerIdentities()
@ -458,12 +462,12 @@ class TwoPartyTradeFlowTests {
val bobsKey = bobNode.services.keyManagementService.keys.single() val bobsKey = bobNode.services.keyManagementService.keys.single()
val bobsFakeCash = fillUpForBuyer(false, issuer, AnonymousParty(bobsKey), val bobsFakeCash = fillUpForBuyer(false, issuer, AnonymousParty(bobsKey),
notaryNode.info.notaryIdentity).second notary).second
insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bankNode) insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bankNode)
val alicesFakePaper = aliceNode.database.transaction { val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(), fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(),
1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), attachmentID, notaryNode.info.notaryIdentity).second 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), attachmentID, notary).second
} }
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode) insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
@ -474,7 +478,7 @@ class TwoPartyTradeFlowTests {
val aliceTxMappings = with(aliceNode) { val aliceTxMappings = with(aliceNode) {
database.transaction { services.stateMachineRecordedTransactionMapping.track().updates } database.transaction { services.stateMachineRecordedTransactionMapping.track().updates }
} }
val aliceSmId = runBuyerAndSeller(notaryNode, aliceNode, bobNode, val aliceSmId = runBuyerAndSeller(notary, aliceNode, bobNode,
"alice's paper".outputStateAndRef()).sellerId "alice's paper".outputStateAndRef()).sellerId
mockNet.runNetwork() mockNet.runNetwork()
@ -533,21 +537,21 @@ class TwoPartyTradeFlowTests {
val sellerId: StateMachineRunId val sellerId: StateMachineRunId
) )
private fun runBuyerAndSeller(notaryNode: StartedNode<MockNetwork.MockNode>, private fun runBuyerAndSeller(notary: Party,
sellerNode: StartedNode<MockNetwork.MockNode>, sellerNode: StartedNode<MockNetwork.MockNode>,
buyerNode: StartedNode<MockNetwork.MockNode>, buyerNode: StartedNode<MockNetwork.MockNode>,
assetToSell: StateAndRef<OwnableState>, assetToSell: StateAndRef<OwnableState>,
anonymous: Boolean = true): RunResult { anonymous: Boolean = true): RunResult {
val buyerFlows: Observable<out FlowLogic<*>> = buyerNode.internals.registerInitiatedFlow(BuyerAcceptor::class.java) val buyerFlows: Observable<out FlowLogic<*>> = buyerNode.internals.registerInitiatedFlow(BuyerAcceptor::class.java)
val firstBuyerFiber = buyerFlows.toFuture().map { it.stateMachine } val firstBuyerFiber = buyerFlows.toFuture().map { it.stateMachine }
val seller = SellerInitiator(buyerNode.info.chooseIdentity(), notaryNode.info, assetToSell, 1000.DOLLARS, anonymous) val seller = SellerInitiator(buyerNode.info.chooseIdentity(), notary, assetToSell, 1000.DOLLARS, anonymous)
val sellerResult = sellerNode.services.startFlow(seller).resultFuture val sellerResult = sellerNode.services.startFlow(seller).resultFuture
return RunResult(firstBuyerFiber, sellerResult, seller.stateMachine.id) return RunResult(firstBuyerFiber, sellerResult, seller.stateMachine.id)
} }
@InitiatingFlow @InitiatingFlow
class SellerInitiator(private val buyer: Party, class SellerInitiator(private val buyer: Party,
private val notary: NodeInfo, private val notary: Party,
private val assetToSell: StateAndRef<OwnableState>, private val assetToSell: StateAndRef<OwnableState>,
private val price: Amount<Currency>, private val price: Amount<Currency>,
private val anonymous: Boolean) : FlowLogic<SignedTransaction>() { private val anonymous: Boolean) : FlowLogic<SignedTransaction>() {
@ -558,10 +562,9 @@ class TwoPartyTradeFlowTests {
} else { } else {
ourIdentityAndCert ourIdentityAndCert
} }
send(buyer, TestTx(notary.notaryIdentity, price, anonymous)) send(buyer, TestTx(notary, price, anonymous))
return subFlow(Seller( return subFlow(Seller(
buyer, buyer,
notary,
assetToSell, assetToSell,
price, price,
myPartyAndCert)) myPartyAndCert))
@ -596,17 +599,18 @@ class TwoPartyTradeFlowTests {
mockNet.runNetwork() mockNet.runNetwork()
notaryNode.internals.ensureRegistered() notaryNode.internals.ensureRegistered()
val notary = aliceNode.services.getDefaultNotary()
// Let the nodes know about each other - normally the network map would handle this // Let the nodes know about each other - normally the network map would handle this
mockNet.registerIdentities() mockNet.registerIdentities()
val bobsBadCash = bobNode.database.transaction { val bobsBadCash = bobNode.database.transaction {
fillUpForBuyer(bobError, issuer, bobNode.info.chooseIdentity(), fillUpForBuyer(bobError, issuer, bobNode.info.chooseIdentity(),
notaryNode.info.notaryIdentity).second notary).second
} }
val alicesFakePaper = aliceNode.database.transaction { val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(aliceError, issuer, aliceNode.info.chooseIdentity(), fillUpForSeller(aliceError, issuer, aliceNode.info.chooseIdentity(),
1200.DOLLARS `issued by` issuer, null, notaryNode.info.notaryIdentity).second 1200.DOLLARS `issued by` issuer, null, notary).second
} }
insertFakeTransactions(bobsBadCash, bobNode, notaryNode, bankNode) insertFakeTransactions(bobsBadCash, bobNode, notaryNode, bankNode)
@ -614,7 +618,7 @@ class TwoPartyTradeFlowTests {
mockNet.runNetwork() // Clear network map registration messages mockNet.runNetwork() // Clear network map registration messages
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notaryNode, aliceNode, bobNode, "alice's paper".outputStateAndRef()) val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef())
mockNet.runNetwork() mockNet.runNetwork()

View File

@ -6,7 +6,6 @@ import net.corda.core.flows.NotaryChangeFlow
import net.corda.core.flows.StateReplacementException import net.corda.core.flows.StateReplacementException
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.node.services.ServiceInfo
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.transactions.WireTransaction import net.corda.core.transactions.WireTransaction
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
@ -14,6 +13,7 @@ import net.corda.core.utilities.seconds
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.node.services.network.NetworkMapService import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.ServiceInfo
import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
@ -36,6 +36,8 @@ class NotaryChangeTests {
lateinit var newNotaryNode: StartedNode<MockNetwork.MockNode> lateinit var newNotaryNode: StartedNode<MockNetwork.MockNode>
lateinit var clientNodeA: StartedNode<MockNetwork.MockNode> lateinit var clientNodeA: StartedNode<MockNetwork.MockNode>
lateinit var clientNodeB: StartedNode<MockNetwork.MockNode> lateinit var clientNodeB: StartedNode<MockNetwork.MockNode>
lateinit var notaryNewId: Party
lateinit var notaryOldId: Party
@Before @Before
fun setUp() { fun setUp() {
@ -49,6 +51,8 @@ class NotaryChangeTests {
mockNet.registerIdentities() mockNet.registerIdentities()
mockNet.runNetwork() // Clear network map registration messages mockNet.runNetwork() // Clear network map registration messages
oldNotaryNode.internals.ensureRegistered() oldNotaryNode.internals.ensureRegistered()
notaryNewId = newNotaryNode.info.legalIdentities[1]
notaryOldId = oldNotaryNode.info.legalIdentities[1]
} }
@After @After
@ -58,8 +62,8 @@ class NotaryChangeTests {
@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, oldNotaryNode) val state = issueState(clientNodeA, oldNotaryNode, notaryOldId)
val newNotary = newNotaryNode.info.notaryIdentity val newNotary = notaryNewId
val flow = NotaryChangeFlow(state, newNotary) val flow = NotaryChangeFlow(state, newNotary)
val future = clientNodeA.services.startFlow(flow) val future = clientNodeA.services.startFlow(flow)
@ -71,8 +75,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, oldNotaryNode) val state = issueMultiPartyState(clientNodeA, clientNodeB, oldNotaryNode, notaryOldId)
val newNotary = newNotaryNode.info.notaryIdentity val newNotary = notaryNewId
val flow = NotaryChangeFlow(state, newNotary) val flow = NotaryChangeFlow(state, newNotary)
val future = clientNodeA.services.startFlow(flow) val future = clientNodeA.services.startFlow(flow)
@ -87,7 +91,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, oldNotaryNode) val state = issueMultiPartyState(clientNodeA, clientNodeB, oldNotaryNode, notaryOldId)
val newEvilNotary = getTestPartyAndCertificate(CordaX500Name(organisation = "Evil R3", locality = "London", country = "GB"), generateKeyPair().public) val newEvilNotary = getTestPartyAndCertificate(CordaX500Name(organisation = "Evil R3", locality = "London", country = "GB"), generateKeyPair().public)
val flow = NotaryChangeFlow(state, newEvilNotary.party) val flow = NotaryChangeFlow(state, newEvilNotary.party)
val future = clientNodeA.services.startFlow(flow) val future = clientNodeA.services.startFlow(flow)
@ -101,10 +105,10 @@ class NotaryChangeTests {
@Test @Test
fun `should not break encumbrance links`() { fun `should not break encumbrance links`() {
val issueTx = issueEncumberedState(clientNodeA, oldNotaryNode) val issueTx = issueEncumberedState(clientNodeA, notaryOldId)
val state = StateAndRef(issueTx.outputs.first(), StateRef(issueTx.id, 0)) val state = StateAndRef(issueTx.outputs.first(), StateRef(issueTx.id, 0))
val newNotary = newNotaryNode.info.notaryIdentity val newNotary = notaryNewId
val flow = NotaryChangeFlow(state, newNotary) val flow = NotaryChangeFlow(state, newNotary)
val future = clientNodeA.services.startFlow(flow) val future = clientNodeA.services.startFlow(flow)
mockNet.runNetwork() mockNet.runNetwork()
@ -133,19 +137,17 @@ class NotaryChangeTests {
} }
} }
private fun issueEncumberedState(node: StartedNode<*>, notaryNode: StartedNode<*>): WireTransaction { private fun issueEncumberedState(node: StartedNode<*>, notaryIdentity: Party): WireTransaction {
val owner = node.info.chooseIdentity().ref(0) val owner = node.info.chooseIdentity().ref(0)
val notary = notaryNode.info.notaryIdentity
val stateA = DummyContract.SingleOwnerState(Random().nextInt(), owner.party) val stateA = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
val stateB = DummyContract.SingleOwnerState(Random().nextInt(), owner.party) val stateB = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
val stateC = DummyContract.SingleOwnerState(Random().nextInt(), owner.party) val stateC = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
val tx = TransactionBuilder(null).apply { val tx = TransactionBuilder(null).apply {
addCommand(Command(DummyContract.Commands.Create(), owner.party.owningKey)) addCommand(Command(DummyContract.Commands.Create(), owner.party.owningKey))
addOutputState(stateA, DUMMY_PROGRAM_ID, notary, encumbrance = 2) // Encumbered by stateB addOutputState(stateA, DUMMY_PROGRAM_ID, notaryIdentity, encumbrance = 2) // Encumbered by stateB
addOutputState(stateC, DUMMY_PROGRAM_ID, notary) addOutputState(stateC, DUMMY_PROGRAM_ID, notaryIdentity)
addOutputState(stateB, DUMMY_PROGRAM_ID, notary, encumbrance = 1) // Encumbered by stateC addOutputState(stateB, DUMMY_PROGRAM_ID, notaryIdentity, encumbrance = 1) // Encumbered by stateC
} }
val stx = node.services.signInitialTransaction(tx) val stx = node.services.signInitialTransaction(tx)
node.services.recordTransactions(stx) node.services.recordTransactions(stx)
@ -161,21 +163,21 @@ 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: StartedNode<*>, notaryNode: StartedNode<*>): StateAndRef<*> { fun issueState(node: StartedNode<*>, notaryNode: StartedNode<*>, notaryIdentity: Party): StateAndRef<*> {
val tx = DummyContract.generateInitial(Random().nextInt(), notaryNode.info.notaryIdentity, node.info.chooseIdentity().ref(0)) val tx = DummyContract.generateInitial(Random().nextInt(), notaryIdentity, node.info.chooseIdentity().ref(0))
val signedByNode = node.services.signInitialTransaction(tx) val signedByNode = node.services.signInitialTransaction(tx)
val stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey) val stx = notaryNode.services.addSignature(signedByNode, notaryIdentity.owningKey)
node.services.recordTransactions(stx) node.services.recordTransactions(stx)
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0)) return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
} }
fun issueMultiPartyState(nodeA: StartedNode<*>, nodeB: StartedNode<*>, notaryNode: StartedNode<*>): StateAndRef<DummyContract.MultiOwnerState> { fun issueMultiPartyState(nodeA: StartedNode<*>, nodeB: StartedNode<*>, notaryNode: StartedNode<*>, notaryIdentity: Party): StateAndRef<DummyContract.MultiOwnerState> {
val state = TransactionState(DummyContract.MultiOwnerState(0, val state = TransactionState(DummyContract.MultiOwnerState(0,
listOf(nodeA.info.chooseIdentity(), nodeB.info.chooseIdentity())), DUMMY_PROGRAM_ID, notaryNode.info.notaryIdentity) listOf(nodeA.info.chooseIdentity(), nodeB.info.chooseIdentity())), DUMMY_PROGRAM_ID, notaryIdentity)
val tx = TransactionBuilder(notary = notaryNode.info.notaryIdentity).withItems(state, dummyCommand()) val tx = TransactionBuilder(notary = notaryIdentity).withItems(state, dummyCommand())
val signedByA = nodeA.services.signInitialTransaction(tx) val signedByA = nodeA.services.signInitialTransaction(tx)
val signedByAB = nodeB.services.addSignature(signedByA) val signedByAB = nodeB.services.addSignature(signedByA)
val stx = notaryNode.services.addSignature(signedByAB, notaryNode.services.notaryIdentityKey) val stx = notaryNode.services.addSignature(signedByAB, notaryIdentity.owningKey)
nodeA.services.recordTransactions(stx) nodeA.services.recordTransactions(stx)
nodeB.services.recordTransactions(stx) nodeB.services.recordTransactions(stx)
val stateAndRef = StateAndRef(state, StateRef(stx.id, 0)) val stateAndRef = StateAndRef(state, StateRef(stx.id, 0))

View File

@ -6,7 +6,6 @@ import net.corda.core.contracts.*
import net.corda.core.flows.* import net.corda.core.flows.*
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.VaultQueryService import net.corda.core.node.services.VaultQueryService
import net.corda.core.node.services.queryBy import net.corda.core.node.services.queryBy
import net.corda.core.node.services.vault.DEFAULT_PAGE_NUM import net.corda.core.node.services.vault.DEFAULT_PAGE_NUM
@ -17,6 +16,7 @@ import net.corda.core.node.services.vault.SortAttribute
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.network.NetworkMapService import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.statemachine.StateMachineManager import net.corda.node.services.statemachine.StateMachineManager
import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.node.services.transactions.ValidatingNotaryService

View File

@ -4,11 +4,10 @@ import net.corda.core.concurrent.CordaFuture
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.services.ServiceInfo
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.node.services.api.ServiceHubInternal import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.messaging.MessagingService import net.corda.node.services.messaging.MessagingService
import net.corda.node.services.messaging.send import net.corda.node.services.messaging.send

View File

@ -1,8 +1,8 @@
package net.corda.node.services.network package net.corda.node.services.network
import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.NetworkMapCache
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.nodeapi.ServiceInfo
import net.corda.testing.ALICE import net.corda.testing.ALICE
import net.corda.testing.BOB import net.corda.testing.BOB
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity

View File

@ -60,8 +60,7 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() {
@Test @Test
fun `restart node with DB map cache and no network map`() { fun `restart node with DB map cache and no network map`() {
val alice = startNodesWithPort(listOf(ALICE), noNetworkMap = true)[0] val alice = startNodesWithPort(listOf(ALICE), noNetworkMap = true)[0]
val partyNodes = alice.services.networkMapCache.partyNodes val partyNodes = alice.services.networkMapCache.allNodes
assertTrue(NetworkMapService.type !in alice.info.advertisedServices.map { it.info.type })
assertEquals(NullNetworkMapService, alice.inNodeNetworkMapService) assertEquals(NullNetworkMapService, alice.inNodeNetworkMapService)
assertEquals(infos.size, partyNodes.size) assertEquals(infos.size, partyNodes.size)
assertEquals(infos.flatMap { it.legalIdentities }.toSet(), partyNodes.flatMap { it.legalIdentities }.toSet()) assertEquals(infos.flatMap { it.legalIdentities }.toSet(), partyNodes.flatMap { it.legalIdentities }.toSet())
@ -72,9 +71,8 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() {
val parties = partiesList.subList(1, partiesList.size) val parties = partiesList.subList(1, partiesList.size)
val nodes = startNodesWithPort(parties, noNetworkMap = true) val nodes = startNodesWithPort(parties, noNetworkMap = true)
assertTrue(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService }) assertTrue(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService })
assertTrue(nodes.all { NetworkMapService.type !in it.info.advertisedServices.map { it.info.type } })
nodes.forEach { nodes.forEach {
val partyNodes = it.services.networkMapCache.partyNodes val partyNodes = it.services.networkMapCache.allNodes
assertEquals(infos.size, partyNodes.size) assertEquals(infos.size, partyNodes.size)
assertEquals(infos.flatMap { it.legalIdentities }.toSet(), partyNodes.flatMap { it.legalIdentities }.toSet()) assertEquals(infos.flatMap { it.legalIdentities }.toSet(), partyNodes.flatMap { it.legalIdentities }.toSet())
} }
@ -86,9 +84,8 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() {
val parties = partiesList.subList(1, partiesList.size) val parties = partiesList.subList(1, partiesList.size)
val nodes = startNodesWithPort(parties, noNetworkMap = false) val nodes = startNodesWithPort(parties, noNetworkMap = false)
assertTrue(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService }) assertTrue(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService })
assertTrue(nodes.all { NetworkMapService.type !in it.info.advertisedServices.map { it.info.type } })
nodes.forEach { nodes.forEach {
val partyNodes = it.services.networkMapCache.partyNodes val partyNodes = it.services.networkMapCache.allNodes
assertEquals(infos.size, partyNodes.size) assertEquals(infos.size, partyNodes.size)
assertEquals(infos.flatMap { it.legalIdentities }.toSet(), partyNodes.flatMap { it.legalIdentities }.toSet()) assertEquals(infos.flatMap { it.legalIdentities }.toSet(), partyNodes.flatMap { it.legalIdentities }.toSet())
} }
@ -118,7 +115,7 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() {
// Start node that is not in databases of other nodes. Point to NMS. Which has't started yet. // Start node that is not in databases of other nodes. Point to NMS. Which has't started yet.
val charlie = startNodesWithPort(listOf(CHARLIE), noNetworkMap = false)[0] val charlie = startNodesWithPort(listOf(CHARLIE), noNetworkMap = false)[0]
otherNodes.forEach { otherNodes.forEach {
assertThat(it.services.networkMapCache.partyNodes).doesNotContain(charlie.info) assertThat(it.services.networkMapCache.allNodes).doesNotContain(charlie.info)
} }
// Start Network Map and see that charlie node appears in caches. // Start Network Map and see that charlie node appears in caches.
val nms = startNodesWithPort(listOf(DUMMY_NOTARY), noNetworkMap = false)[0] val nms = startNodesWithPort(listOf(DUMMY_NOTARY), noNetworkMap = false)[0]
@ -126,13 +123,13 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() {
assertTrue(nms.inNodeNetworkMapService != NullNetworkMapService) assertTrue(nms.inNodeNetworkMapService != NullNetworkMapService)
assertTrue(infos.any { it.legalIdentities.toSet() == nms.info.legalIdentities.toSet() }) assertTrue(infos.any { it.legalIdentities.toSet() == nms.info.legalIdentities.toSet() })
otherNodes.forEach { otherNodes.forEach {
assertTrue(nms.info.chooseIdentity() in it.services.networkMapCache.partyNodes.map { it.chooseIdentity() }) assertTrue(nms.info.chooseIdentity() in it.services.networkMapCache.allNodes.map { it.chooseIdentity() })
} }
charlie.internals.nodeReadyFuture.get() // Finish registration. charlie.internals.nodeReadyFuture.get() // Finish registration.
checkConnectivity(listOf(otherNodes[0], nms)) // Checks connectivity from A to NMS. checkConnectivity(listOf(otherNodes[0], nms)) // Checks connectivity from A to NMS.
val cacheA = otherNodes[0].services.networkMapCache.partyNodes val cacheA = otherNodes[0].services.networkMapCache.allNodes
val cacheB = otherNodes[1].services.networkMapCache.partyNodes val cacheB = otherNodes[1].services.networkMapCache.allNodes
val cacheC = charlie.services.networkMapCache.partyNodes val cacheC = charlie.services.networkMapCache.allNodes
assertEquals(4, cacheC.size) // Charlie fetched data from NetworkMap assertEquals(4, cacheC.size) // Charlie fetched data from NetworkMap
assertThat(cacheB).contains(charlie.info) assertThat(cacheB).contains(charlie.info)
assertEquals(cacheA.toSet(), cacheB.toSet()) assertEquals(cacheA.toSet(), cacheB.toSet())

View File

@ -1,7 +1,7 @@
package net.corda.node.services.network package net.corda.node.services.network
import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.services.ServiceInfo import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork

View File

@ -15,7 +15,6 @@ import net.corda.core.internal.concurrent.flatMap
import net.corda.core.internal.concurrent.map import net.corda.core.internal.concurrent.map
import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.MessageRecipients
import net.corda.core.node.services.PartyInfo import net.corda.core.node.services.PartyInfo
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.queryBy import net.corda.core.node.services.queryBy
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
@ -32,6 +31,7 @@ import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.internal.InitiatedFlowFactory import net.corda.node.internal.InitiatedFlowFactory
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.network.NetworkMapService import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.persistence.checkpoints import net.corda.node.services.persistence.checkpoints
import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.node.services.transactions.ValidatingNotaryService
@ -72,6 +72,8 @@ class FlowFrameworkTests {
private lateinit var node2: StartedNode<MockNode> private lateinit var node2: StartedNode<MockNode>
private lateinit var notary1: StartedNode<MockNode> private lateinit var notary1: StartedNode<MockNode>
private lateinit var notary2: StartedNode<MockNode> private lateinit var notary2: StartedNode<MockNode>
private lateinit var notary1Identity: Party
private lateinit var notary2Identity: Party
@Before @Before
fun start() { fun start() {
@ -95,6 +97,8 @@ class FlowFrameworkTests {
// We don't create a network map, so manually handle registrations // We don't create a network map, so manually handle registrations
mockNet.registerIdentities() mockNet.registerIdentities()
notary1Identity = notary1.services.myInfo.legalIdentities[1]
notary2Identity = notary2.services.myInfo.legalIdentities[1]
} }
@After @After
@ -333,11 +337,12 @@ class FlowFrameworkTests {
@Test @Test
fun `different notaries are picked when addressing shared notary identity`() { fun `different notaries are picked when addressing shared notary identity`() {
assertEquals(notary1.info.notaryIdentity, notary2.info.notaryIdentity) assertEquals(notary1Identity, notary2Identity)
assertThat(node1.services.networkMapCache.notaryIdentities.size == 1)
node1.services.startFlow(CashIssueFlow( node1.services.startFlow(CashIssueFlow(
2000.DOLLARS, 2000.DOLLARS,
OpaqueBytes.of(0x01), OpaqueBytes.of(0x01),
notary1.info.notaryIdentity)).resultFuture.getOrThrow() notary1Identity)).resultFuture.getOrThrow()
// We pay a couple of times, the notary picking should go round robin // We pay a couple of times, the notary picking should go round robin
for (i in 1..3) { for (i in 1..3) {
val flow = node1.services.startFlow(CashPaymentFlow(500.DOLLARS, node2.info.chooseIdentity())) val flow = node1.services.startFlow(CashPaymentFlow(500.DOLLARS, node2.info.chooseIdentity()))
@ -345,11 +350,11 @@ class FlowFrameworkTests {
flow.resultFuture.getOrThrow() flow.resultFuture.getOrThrow()
} }
val endpoint = mockNet.messagingNetwork.endpoint(notary1.network.myAddress as InMemoryMessagingNetwork.PeerHandle)!! val endpoint = mockNet.messagingNetwork.endpoint(notary1.network.myAddress as InMemoryMessagingNetwork.PeerHandle)!!
val party1Info = notary1.services.networkMapCache.getPartyInfo(notary1.info.notaryIdentity)!! val party1Info = notary1.services.networkMapCache.getPartyInfo(notary1Identity)!!
assertTrue(party1Info is PartyInfo.DistributedNode) assertTrue(party1Info is PartyInfo.DistributedNode)
val notary1Address: MessageRecipients = endpoint.getAddressOfParty(notary1.services.networkMapCache.getPartyInfo(notary1.info.notaryIdentity)!!) val notary1Address: MessageRecipients = endpoint.getAddressOfParty(notary1.services.networkMapCache.getPartyInfo(notary1Identity)!!)
assertThat(notary1Address).isInstanceOf(InMemoryMessagingNetwork.ServiceHandle::class.java) assertThat(notary1Address).isInstanceOf(InMemoryMessagingNetwork.ServiceHandle::class.java)
assertEquals(notary1Address, endpoint.getAddressOfParty(notary2.services.networkMapCache.getPartyInfo(notary2.info.notaryIdentity)!!)) assertEquals(notary1Address, endpoint.getAddressOfParty(notary2.services.networkMapCache.getPartyInfo(notary2Identity)!!))
receivedSessionMessages.expectEvents(isStrict = false) { receivedSessionMessages.expectEvents(isStrict = false) {
sequence( sequence(
// First Pay // First Pay
@ -598,7 +603,7 @@ class FlowFrameworkTests {
@Test @Test
fun `wait for transaction`() { fun `wait for transaction`() {
val ptx = TransactionBuilder(notary = notary1.info.notaryIdentity) val ptx = TransactionBuilder(notary = notary1Identity)
.addOutputState(DummyState(), DUMMY_PROGRAM_ID) .addOutputState(DummyState(), DUMMY_PROGRAM_ID)
.addCommand(dummyCommand(node1.info.chooseIdentity().owningKey)) .addCommand(dummyCommand(node1.info.chooseIdentity().owningKey))
val stx = node1.services.signInitialTransaction(ptx) val stx = node1.services.signInitialTransaction(ptx)
@ -613,7 +618,7 @@ class FlowFrameworkTests {
@Test @Test
fun `committer throws exception before calling the finality flow`() { fun `committer throws exception before calling the finality flow`() {
val ptx = TransactionBuilder(notary = notary1.info.notaryIdentity) val ptx = TransactionBuilder(notary = notary1Identity)
.addOutputState(DummyState(), DUMMY_PROGRAM_ID) .addOutputState(DummyState(), DUMMY_PROGRAM_ID)
.addCommand(dummyCommand()) .addCommand(dummyCommand())
val stx = node1.services.signInitialTransaction(ptx) val stx = node1.services.signInitialTransaction(ptx)
@ -630,7 +635,7 @@ class FlowFrameworkTests {
@Test @Test
fun `verify vault query service is tokenizable by force checkpointing within a flow`() { fun `verify vault query service is tokenizable by force checkpointing within a flow`() {
val ptx = TransactionBuilder(notary = notary1.info.notaryIdentity) val ptx = TransactionBuilder(notary = notary1Identity)
.addOutputState(DummyState(), DUMMY_PROGRAM_ID) .addOutputState(DummyState(), DUMMY_PROGRAM_ID)
.addCommand(dummyCommand(node1.info.chooseIdentity().owningKey)) .addCommand(dummyCommand(node1.info.chooseIdentity().owningKey))
val stx = node1.services.signInitialTransaction(ptx) val stx = node1.services.signInitialTransaction(ptx)

View File

@ -7,17 +7,19 @@ import net.corda.core.crypto.TransactionSignature
import net.corda.core.flows.NotaryError import net.corda.core.flows.NotaryError
import net.corda.core.flows.NotaryException import net.corda.core.flows.NotaryException
import net.corda.core.flows.NotaryFlow import net.corda.core.flows.NotaryFlow
import net.corda.core.node.services.ServiceInfo import net.corda.core.identity.Party
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.seconds import net.corda.core.utilities.seconds
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.network.NetworkMapService import net.corda.node.services.network.NetworkMapService
import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.dummyCommand import net.corda.testing.dummyCommand
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.After import org.junit.After
@ -32,6 +34,7 @@ class NotaryServiceTests {
lateinit var mockNet: MockNetwork lateinit var mockNet: MockNetwork
lateinit var notaryNode: StartedNode<MockNetwork.MockNode> lateinit var notaryNode: StartedNode<MockNetwork.MockNode>
lateinit var clientNode: StartedNode<MockNetwork.MockNode> lateinit var clientNode: StartedNode<MockNetwork.MockNode>
lateinit var notary: Party
@Before @Before
fun setup() { fun setup() {
@ -42,6 +45,7 @@ class NotaryServiceTests {
clientNode = mockNet.createNode(notaryNode.network.myAddress) clientNode = mockNet.createNode(notaryNode.network.myAddress)
mockNet.runNetwork() // Clear network map registration messages mockNet.runNetwork() // Clear network map registration messages
notaryNode.internals.ensureRegistered() notaryNode.internals.ensureRegistered()
notary = clientNode.services.getDefaultNotary()
} }
@After @After
@ -53,7 +57,7 @@ class NotaryServiceTests {
fun `should sign a unique transaction with a valid time-window`() { fun `should sign a unique transaction with a valid time-window`() {
val stx = run { val stx = run {
val inputState = issueState(clientNode) val inputState = issueState(clientNode)
val tx = TransactionBuilder(notaryNode.info.notaryIdentity) val tx = TransactionBuilder(notary)
.addInputState(inputState) .addInputState(inputState)
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey)) .addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
.setTimeWindow(Instant.now(), 30.seconds) .setTimeWindow(Instant.now(), 30.seconds)
@ -69,7 +73,7 @@ class NotaryServiceTests {
fun `should sign a unique transaction without a time-window`() { fun `should sign a unique transaction without a time-window`() {
val stx = run { val stx = run {
val inputState = issueState(clientNode) val inputState = issueState(clientNode)
val tx = TransactionBuilder(notaryNode.info.notaryIdentity) val tx = TransactionBuilder(notary)
.addInputState(inputState) .addInputState(inputState)
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey)) .addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
clientNode.services.signInitialTransaction(tx) clientNode.services.signInitialTransaction(tx)
@ -84,7 +88,7 @@ class NotaryServiceTests {
fun `should report error for transaction with an invalid time-window`() { fun `should report error for transaction with an invalid time-window`() {
val stx = run { val stx = run {
val inputState = issueState(clientNode) val inputState = issueState(clientNode)
val tx = TransactionBuilder(notaryNode.info.notaryIdentity) val tx = TransactionBuilder(notary)
.addInputState(inputState) .addInputState(inputState)
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey)) .addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
.setTimeWindow(Instant.now().plusSeconds(3600), 30.seconds) .setTimeWindow(Instant.now().plusSeconds(3600), 30.seconds)
@ -101,7 +105,7 @@ class NotaryServiceTests {
fun `should sign identical transaction multiple times (signing is idempotent)`() { fun `should sign identical transaction multiple times (signing is idempotent)`() {
val stx = run { val stx = run {
val inputState = issueState(clientNode) val inputState = issueState(clientNode)
val tx = TransactionBuilder(notaryNode.info.notaryIdentity) val tx = TransactionBuilder(notary)
.addInputState(inputState) .addInputState(inputState)
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey)) .addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
clientNode.services.signInitialTransaction(tx) clientNode.services.signInitialTransaction(tx)
@ -121,13 +125,13 @@ class NotaryServiceTests {
fun `should report conflict when inputs are reused across transactions`() { fun `should report conflict when inputs are reused across transactions`() {
val inputState = issueState(clientNode) val inputState = issueState(clientNode)
val stx = run { val stx = run {
val tx = TransactionBuilder(notaryNode.info.notaryIdentity) val tx = TransactionBuilder(notary)
.addInputState(inputState) .addInputState(inputState)
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey)) .addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
clientNode.services.signInitialTransaction(tx) clientNode.services.signInitialTransaction(tx)
} }
val stx2 = run { val stx2 = run {
val tx = TransactionBuilder(notaryNode.info.notaryIdentity) val tx = TransactionBuilder(notary)
.addInputState(inputState) .addInputState(inputState)
.addInputState(issueState(clientNode)) .addInputState(issueState(clientNode))
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey)) .addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
@ -155,7 +159,7 @@ class NotaryServiceTests {
} }
fun issueState(node: StartedNode<*>): StateAndRef<*> { fun issueState(node: StartedNode<*>): StateAndRef<*> {
val tx = DummyContract.generateInitial(Random().nextInt(), notaryNode.info.notaryIdentity, node.info.chooseIdentity().ref(0)) val tx = DummyContract.generateInitial(Random().nextInt(), notary, node.info.chooseIdentity().ref(0))
val signedByNode = node.services.signInitialTransaction(tx) val signedByNode = node.services.signInitialTransaction(tx)
val stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey) val stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey)
node.services.recordTransactions(stx) node.services.recordTransactions(stx)

View File

@ -8,11 +8,12 @@ import net.corda.core.crypto.TransactionSignature
import net.corda.core.flows.NotaryError import net.corda.core.flows.NotaryError
import net.corda.core.flows.NotaryException import net.corda.core.flows.NotaryException
import net.corda.core.flows.NotaryFlow import net.corda.core.flows.NotaryFlow
import net.corda.core.node.services.ServiceInfo import net.corda.core.identity.Party
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.issueInvalidState import net.corda.node.services.issueInvalidState
import net.corda.node.services.network.NetworkMapService import net.corda.node.services.network.NetworkMapService
import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY
@ -20,6 +21,7 @@ import net.corda.testing.MEGA_CORP_KEY
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.dummyCommand import net.corda.testing.dummyCommand
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.After import org.junit.After
@ -33,6 +35,7 @@ class ValidatingNotaryServiceTests {
lateinit var mockNet: MockNetwork lateinit var mockNet: MockNetwork
lateinit var notaryNode: StartedNode<MockNetwork.MockNode> lateinit var notaryNode: StartedNode<MockNetwork.MockNode>
lateinit var clientNode: StartedNode<MockNetwork.MockNode> lateinit var clientNode: StartedNode<MockNetwork.MockNode>
lateinit var notary: Party
@Before @Before
fun setup() { fun setup() {
@ -44,6 +47,7 @@ class ValidatingNotaryServiceTests {
clientNode = mockNet.createNode(notaryNode.network.myAddress) clientNode = mockNet.createNode(notaryNode.network.myAddress)
mockNet.runNetwork() // Clear network map registration messages mockNet.runNetwork() // Clear network map registration messages
notaryNode.internals.ensureRegistered() notaryNode.internals.ensureRegistered()
notary = clientNode.services.getDefaultNotary()
} }
@After @After
@ -54,8 +58,8 @@ class ValidatingNotaryServiceTests {
@Test @Test
fun `should report error for invalid transaction dependency`() { fun `should report error for invalid transaction dependency`() {
val stx = run { val stx = run {
val inputState = issueInvalidState(clientNode, notaryNode.info.notaryIdentity) val inputState = issueInvalidState(clientNode, notary)
val tx = TransactionBuilder(notaryNode.info.notaryIdentity) val tx = TransactionBuilder(notary)
.addInputState(inputState) .addInputState(inputState)
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey)) .addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
clientNode.services.signInitialTransaction(tx) clientNode.services.signInitialTransaction(tx)
@ -75,7 +79,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 = TransactionBuilder(notaryNode.info.notaryIdentity).withItems(inputState, command) val tx = TransactionBuilder(notary).withItems(inputState, command)
clientNode.services.signInitialTransaction(tx) clientNode.services.signInitialTransaction(tx)
} }
@ -98,7 +102,7 @@ class ValidatingNotaryServiceTests {
} }
fun issueState(node: StartedNode<*>): StateAndRef<*> { fun issueState(node: StartedNode<*>): StateAndRef<*> {
val tx = DummyContract.generateInitial(Random().nextInt(), notaryNode.info.notaryIdentity, node.info.chooseIdentity().ref(0)) val tx = DummyContract.generateInitial(Random().nextInt(), notary, node.info.chooseIdentity().ref(0))
val signedByNode = node.services.signInitialTransaction(tx) val signedByNode = node.services.signInitialTransaction(tx)
val stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey) val stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey)
node.services.recordTransactions(stx) node.services.recordTransactions(stx)

View File

@ -1,8 +1,8 @@
package net.corda.attachmentdemo package net.corda.attachmentdemo
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_BANK_A

View File

@ -1,7 +1,7 @@
package net.corda.attachmentdemo package net.corda.attachmentdemo
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.node.services.ServiceInfo import net.corda.nodeapi.ServiceInfo
import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_BANK_A
import net.corda.testing.DUMMY_BANK_B import net.corda.testing.DUMMY_BANK_B
import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY

View File

@ -2,8 +2,8 @@ package net.corda.bank
import net.corda.bank.api.BankOfCordaClientApi import net.corda.bank.api.BankOfCordaClientApi
import net.corda.bank.api.BankOfCordaWebApi.IssueRequestParams import net.corda.bank.api.BankOfCordaWebApi.IssueRequestParams
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.testing.BOC import net.corda.testing.BOC
import net.corda.testing.driver.driver import net.corda.testing.driver.driver

View File

@ -1,7 +1,6 @@
package net.corda.bank package net.corda.bank
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
import net.corda.core.node.services.vault.QueryCriteria import net.corda.core.node.services.vault.QueryCriteria
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
@ -9,6 +8,7 @@ import net.corda.finance.DOLLARS
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.flows.CashIssueAndPaymentFlow import net.corda.finance.flows.CashIssueAndPaymentFlow
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.* import net.corda.testing.*
@ -33,6 +33,8 @@ class BankOfCordaRPCClientTest {
// Big Corporation RPC Client // Big Corporation RPC Client
val bigCorpClient = nodeBigCorporation.rpcClientToNode() val bigCorpClient = nodeBigCorporation.rpcClientToNode()
val bigCorpProxy = bigCorpClient.start("bigCorpCFO", "password2").proxy val bigCorpProxy = bigCorpClient.start("bigCorpCFO", "password2").proxy
bocProxy.waitUntilNetworkReady()
bigCorpProxy.waitUntilNetworkReady()
// Register for Bank of Corda Vault updates // Register for Bank of Corda Vault updates
val criteria = QueryCriteria.VaultQueryCriteria(status = Vault.StateStatus.ALL) val criteria = QueryCriteria.VaultQueryCriteria(status = Vault.StateStatus.ALL)
@ -43,11 +45,12 @@ class BankOfCordaRPCClientTest {
// Kick-off actual Issuer Flow // Kick-off actual Issuer Flow
val anonymous = true val anonymous = true
val notary = bocProxy.notaryIdentities().first().party
bocProxy.startFlow(::CashIssueAndPaymentFlow, bocProxy.startFlow(::CashIssueAndPaymentFlow,
1000.DOLLARS, BIG_CORP_PARTY_REF, 1000.DOLLARS, BIG_CORP_PARTY_REF,
nodeBigCorporation.nodeInfo.chooseIdentity(), nodeBigCorporation.nodeInfo.chooseIdentity(),
anonymous, anonymous,
nodeBankOfCorda.nodeInfo.notaryIdentity).returnValue.getOrThrow() notary).returnValue.getOrThrow()
// Check Bank of Corda Vault Updates // Check Bank of Corda Vault Updates
vaultUpdatesBoc.expectEvents { vaultUpdatesBoc.expectEvents {

View File

@ -4,13 +4,12 @@ import joptsimple.OptionParser
import net.corda.bank.api.BankOfCordaClientApi import net.corda.bank.api.BankOfCordaClientApi
import net.corda.bank.api.BankOfCordaWebApi.IssueRequestParams import net.corda.bank.api.BankOfCordaWebApi.IssueRequestParams
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.ServiceType
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.finance.flows.CashExitFlow import net.corda.finance.flows.CashExitFlow
import net.corda.finance.flows.CashIssueAndPaymentFlow import net.corda.finance.flows.CashIssueAndPaymentFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.BOC import net.corda.testing.BOC
@ -74,8 +73,7 @@ private class BankOfCordaDriver {
advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))) advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
val bankOfCorda = startNode( val bankOfCorda = startNode(
providedName = BOC.name, providedName = BOC.name,
rpcUsers = listOf(bankUser), rpcUsers = listOf(bankUser))
advertisedServices = setOf(ServiceInfo(ServiceType.corda.getSubType("issuer.USD"))))
startNode(providedName = BIGCORP_LEGAL_NAME, rpcUsers = listOf(bigCorpUser)) startNode(providedName = BIGCORP_LEGAL_NAME, rpcUsers = listOf(bigCorpUser))
startWebserver(bankOfCorda.get()) startWebserver(bankOfCorda.get())
waitForAllNodesToFinish() waitForAllNodesToFinish()

View File

@ -36,20 +36,19 @@ class BankOfCordaClientApi(val hostAndPort: NetworkHostAndPort) {
// TODO: privileged security controls required // TODO: privileged security controls required
client.start("bankUser", "test").use { connection -> client.start("bankUser", "test").use { connection ->
val rpc = connection.proxy val rpc = connection.proxy
rpc.waitUntilNetworkReady()
// Resolve parties via RPC // Resolve parties via RPC
val issueToParty = rpc.partyFromX500Name(params.issueToPartyName) val issueToParty = rpc.partyFromX500Name(params.issueToPartyName)
?: throw Exception("Unable to locate ${params.issueToPartyName} in Network Map Service") ?: throw Exception("Unable to locate ${params.issueToPartyName} in Network Map Service")
val notaryLegalIdentity = rpc.partyFromX500Name(params.notaryName) val notaryLegalIdentity = rpc.partyFromX500Name(params.notaryName)
?: throw IllegalStateException("Unable to locate ${params.notaryName} in Network Map Service") ?: throw IllegalStateException("Unable to locate ${params.notaryName} in Network Map Service")
val notaryNode = rpc.nodeIdentityFromParty(notaryLegalIdentity)
?: throw IllegalStateException("Unable to locate notary node in network map cache")
val amount = Amount(params.amount, Currency.getInstance(params.currency)) val amount = Amount(params.amount, Currency.getInstance(params.currency))
val anonymous = true val anonymous = true
val issuerBankPartyRef = OpaqueBytes.of(params.issuerBankPartyRef.toByte()) val issuerBankPartyRef = OpaqueBytes.of(params.issuerBankPartyRef.toByte())
return rpc.startFlow(::CashIssueAndPaymentFlow, amount, issuerBankPartyRef, issueToParty, anonymous, notaryNode.notaryIdentity) return rpc.startFlow(::CashIssueAndPaymentFlow, amount, issuerBankPartyRef, issueToParty, anonymous, notaryLegalIdentity)
.returnValue.getOrThrow().stx .returnValue.getOrThrow().stx
} }
} }

View File

@ -46,8 +46,6 @@ class BankOfCordaWebApi(val rpc: CordaRPCOps) {
rpc.partyFromX500Name(params.issuerBankName) ?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate ${params.issuerBankName} in identity service").build() rpc.partyFromX500Name(params.issuerBankName) ?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate ${params.issuerBankName} in identity service").build()
val notaryParty = rpc.partyFromX500Name(params.notaryName) val notaryParty = rpc.partyFromX500Name(params.notaryName)
?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate ${params.notaryName} in identity service").build() ?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate ${params.notaryName} in identity service").build()
val notaryNode = rpc.nodeIdentityFromParty(notaryParty)
?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate $notaryParty in network map service").build()
val amount = Amount(params.amount, Currency.getInstance(params.currency)) val amount = Amount(params.amount, Currency.getInstance(params.currency))
val anonymous = true val anonymous = true
@ -56,7 +54,7 @@ class BankOfCordaWebApi(val rpc: CordaRPCOps) {
// invoke client side of Issuer Flow: IssuanceRequester // invoke client side of Issuer Flow: IssuanceRequester
// The line below blocks and waits for the future to resolve. // The line below blocks and waits for the future to resolve.
return try { return try {
rpc.startFlow(::CashIssueAndPaymentFlow, amount, issuerBankPartyRef, issueToParty, anonymous, notaryNode.notaryIdentity).returnValue.getOrThrow() rpc.startFlow(::CashIssueAndPaymentFlow, amount, issuerBankPartyRef, issueToParty, anonymous, notaryParty).returnValue.getOrThrow()
logger.info("Issue and payment request completed successfully: $params") logger.info("Issue and payment request completed successfully: $params")
Response.status(Response.Status.CREATED).build() Response.status(Response.Status.CREATED).build()
} catch (e: Exception) { } catch (e: Exception) {

View File

@ -12,7 +12,6 @@ import net.corda.client.rpc.CordaRPCClient
import net.corda.core.contracts.UniqueIdentifier import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.messaging.vaultTrackBy import net.corda.core.messaging.vaultTrackBy
import net.corda.core.node.services.ServiceInfo
import net.corda.core.toFuture import net.corda.core.toFuture
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
@ -21,6 +20,7 @@ import net.corda.core.utilities.seconds
import net.corda.finance.plugin.registerFinanceJSONMappers import net.corda.finance.plugin.registerFinanceJSONMappers
import net.corda.irs.contract.InterestRateSwap import net.corda.irs.contract.InterestRateSwap
import net.corda.irs.utilities.uploadFile import net.corda.irs.utilities.uploadFile
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.config.FullNodeConfiguration import net.corda.node.services.config.FullNodeConfiguration
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User import net.corda.nodeapi.User

View File

@ -47,8 +47,8 @@ object AutoOfferFlow {
@Suspendable @Suspendable
override fun call(): SignedTransaction { override fun call(): SignedTransaction {
require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" } require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" }
val notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity val notary = serviceHub.networkMapCache.notaryIdentities.first().party // TODO We should pass the notary as a parameter to the flow, not leave it to random choice.
// need to pick which ever party is not us // need to pick which ever party is not us
val otherParty = notUs(dealToBeOffered.participants).map { serviceHub.identityService.partyFromAnonymous(it) }.requireNoNulls().single() val otherParty = notUs(dealToBeOffered.participants).map { serviceHub.identityService.partyFromAnonymous(it) }.requireNoNulls().single()
progressTracker.currentStep = DEALING progressTracker.currentStep = DEALING

View File

@ -100,9 +100,7 @@ object FixingFlow {
StateAndRef(state, payload.ref) StateAndRef(state, payload.ref)
} }
override val notaryNode: NodeInfo get() { override val notaryParty: Party get() = dealToFix.state.notary
return serviceHub.networkMapCache.notaryNodes.single { it.notaryIdentity == dealToFix.state.notary }
}
@Suspendable override fun checkProposal(stx: SignedTransaction) = requireThat { @Suspendable override fun checkProposal(stx: SignedTransaction) = requireThat {
// Add some constraints here. // Add some constraints here.

View File

@ -1,7 +1,7 @@
package net.corda.irs package net.corda.irs
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_BANK_A
import net.corda.testing.DUMMY_BANK_B import net.corda.testing.DUMMY_BANK_B

View File

@ -54,9 +54,11 @@ object UpdateBusinessDayFlow {
* the notary or counterparty still use the old clock, so the time-window on the transaction does not validate. * the notary or counterparty still use the old clock, so the time-window on the transaction does not validate.
*/ */
private fun getRecipients(): Iterable<Party> { private fun getRecipients(): Iterable<Party> {
val notaryNodes = serviceHub.networkMapCache.notaryNodes.map { it.legalIdentitiesAndCerts.first().party } // TODO Will break on distributed nodes, but it will change after services removal. val notaryParties = serviceHub.networkMapCache.notaryIdentities.map { it.party }
val partyNodes = (serviceHub.networkMapCache.partyNodes.map { it.legalIdentitiesAndCerts.first().party } - notaryNodes).sortedBy { it.name.toString() } val peerParties = serviceHub.networkMapCache.allNodes.filter {
return notaryNodes + partyNodes it.legalIdentities.all { !serviceHub.networkMapCache.isNotary(it) }
}.map { it.legalIdentities[0] }.sortedBy { it.name.toString() }
return notaryParties + peerParties
} }
@Suspendable @Suspendable

View File

@ -138,6 +138,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten
node1.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java) node1.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java)
node2.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java) node2.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java)
val notaryId = node1.rpcOps.notaryIdentities().first().party
@InitiatingFlow @InitiatingFlow
class StartDealFlow(val otherParty: Party, class StartDealFlow(val otherParty: Party,
val payload: AutoOffer) : FlowLogic<SignedTransaction>() { val payload: AutoOffer) : FlowLogic<SignedTransaction>() {
@ -160,7 +161,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten
val instigator = StartDealFlow( val instigator = StartDealFlow(
node2.info.chooseIdentity(), node2.info.chooseIdentity(),
AutoOffer(notary.info.notaryIdentity, irs)) AutoOffer(notaryId, irs)) // TODO Pass notary as parameter to Simulation.
val instigatorTxFuture = node1.services.startFlow(instigator).resultFuture val instigatorTxFuture = node1.services.startFlow(instigator).resultFuture
return allOf(instigatorTxFuture.toCompletableFuture(), acceptorTxFuture).thenCompose { instigatorTxFuture.toCompletableFuture() } return allOf(instigatorTxFuture.toCompletableFuture(), acceptorTxFuture).thenCompose { instigatorTxFuture.toCompletableFuture() }

View File

@ -6,11 +6,11 @@ import net.corda.finance.utils.CityDatabase
import net.corda.finance.utils.WorldMapLocation import net.corda.finance.utils.WorldMapLocation
import net.corda.core.internal.uncheckedCast import net.corda.core.internal.uncheckedCast
import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.ServiceType
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
import net.corda.irs.api.NodeInterestRates import net.corda.irs.api.NodeInterestRates
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.nodeapi.ServiceType
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.network.NetworkMapService import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.statemachine.StateMachineManager import net.corda.node.services.statemachine.StateMachineManager

View File

@ -7,8 +7,8 @@ import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.stream import net.corda.core.internal.stream
import net.corda.core.internal.toTypedArray import net.corda.core.internal.toTypedArray
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.BFTNonValidatingNotaryService import net.corda.node.services.transactions.BFTNonValidatingNotaryService
import net.corda.node.services.transactions.minCorrectReplicas import net.corda.node.services.transactions.minCorrectReplicas
import net.corda.node.utilities.ServiceIdentityGenerator import net.corda.node.utilities.ServiceIdentityGenerator

View File

@ -26,8 +26,7 @@ fun main(args: Array<String>) {
/** Interface for using the notary demo API from a client. */ /** Interface for using the notary demo API from a client. */
private class NotaryDemoClientApi(val rpc: CordaRPCOps) { private class NotaryDemoClientApi(val rpc: CordaRPCOps) {
private val notary by lazy { private val notary by lazy {
val parties = rpc.networkMapSnapshot() val id = rpc.notaryIdentities().distinct().singleOrNull()?.party
val id = parties.stream().filter { it.advertisedServices.any { it.info.type.isNotary() } }.map { it.notaryIdentity }.distinct().asSequence().singleOrNull()
checkNotNull(id) { "No unique notary identity, try cleaning the node directories." } checkNotNull(id) { "No unique notary identity, try cleaning the node directories." }
} }

View File

@ -5,8 +5,8 @@ import net.corda.cordform.CordformDefinition
import net.corda.cordform.CordformNode import net.corda.cordform.CordformNode
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.RaftValidatingNotaryService import net.corda.node.services.transactions.RaftValidatingNotaryService
import net.corda.node.utilities.ServiceIdentityGenerator import net.corda.node.utilities.ServiceIdentityGenerator
import net.corda.testing.ALICE import net.corda.testing.ALICE

View File

@ -1,7 +1,6 @@
package net.corda.notarydemo package net.corda.notarydemo
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.node.services.ServiceInfo
import net.corda.testing.ALICE import net.corda.testing.ALICE
import net.corda.testing.BOB import net.corda.testing.BOB
import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY
@ -12,6 +11,7 @@ import net.corda.notarydemo.flows.DummyIssueAndMove
import net.corda.notarydemo.flows.RPCStartableNotaryFlowClient import net.corda.notarydemo.flows.RPCStartableNotaryFlowClient
import net.corda.cordform.CordformDefinition import net.corda.cordform.CordformDefinition
import net.corda.cordform.CordformContext import net.corda.cordform.CordformContext
import net.corda.nodeapi.ServiceInfo
import net.corda.testing.internal.demorun.* import net.corda.testing.internal.demorun.*
fun main(args: Array<String>) = SingleNotaryCordform.runNodes() fun main(args: Array<String>) = SingleNotaryCordform.runNodes()

View File

@ -2,8 +2,8 @@ package net.corda.vega
import com.opengamma.strata.product.common.BuySell import com.opengamma.strata.product.common.BuySell
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_BANK_A
import net.corda.testing.DUMMY_BANK_B import net.corda.testing.DUMMY_BANK_B

View File

@ -10,7 +10,6 @@ import net.corda.core.identity.Party
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.messaging.vaultQueryBy import net.corda.core.messaging.vaultQueryBy
import net.corda.core.node.services.ServiceType
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.finance.contracts.DealState import net.corda.finance.contracts.DealState
import net.corda.vega.analytics.InitialMarginTriple import net.corda.vega.analytics.InitialMarginTriple
@ -22,7 +21,6 @@ import net.corda.vega.flows.SimmRevaluation
import net.corda.vega.portfolio.Portfolio import net.corda.vega.portfolio.Portfolio
import net.corda.vega.portfolio.toPortfolio import net.corda.vega.portfolio.toPortfolio
import net.corda.vega.portfolio.toStateAndRef import net.corda.vega.portfolio.toStateAndRef
import org.bouncycastle.asn1.x500.X500Name
import java.time.LocalDate import java.time.LocalDate
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.ZoneId import java.time.ZoneId
@ -254,11 +252,11 @@ class PortfolioApi(val rpc: CordaRPCOps) {
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
fun getWhoAmI(): AvailableParties { fun getWhoAmI(): AvailableParties {
val parties = rpc.networkMapSnapshot() val parties = rpc.networkMapSnapshot()
val counterParties = parties.filterNot { val notaries = rpc.notaryIdentities()
it.advertisedServices.any { it.info.type in setOf(ServiceType.networkMap, ServiceType.notary) } // TODO We are not able to filter by network map node now
|| ownParty in it.legalIdentitiesAndCerts.map { it.party } val counterParties = parties.filterNot { it.legalIdentitiesAndCerts.any { it in notaries }
|| ownParty in it.legalIdentities
} }
return AvailableParties( return AvailableParties(
self = ApiParty(ownParty.owningKey.toBase58String(), ownParty.name), self = ApiParty(ownParty.owningKey.toBase58String(), ownParty.name),
// TODO It will show all identities including service identities. // TODO It will show all identities including service identities.

View File

@ -22,8 +22,8 @@ object IRSTradeFlow {
class Requester(val swap: SwapData, val otherParty: Party) : FlowLogic<SignedTransaction>() { class Requester(val swap: SwapData, val otherParty: Party) : FlowLogic<SignedTransaction>() {
@Suspendable @Suspendable
override fun call(): SignedTransaction { override fun call(): SignedTransaction {
require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" } require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" }
val notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity val notary = serviceHub.networkMapCache.notaryIdentities.first().party // TODO We should pass the notary as a parameter to the flow, not leave it to random choice.
val (buyer, seller) = val (buyer, seller) =
if (swap.buyer.second == ourIdentity.owningKey) { if (swap.buyer.second == ourIdentity.owningKey) {
Pair(ourIdentity, otherParty) Pair(ourIdentity, otherParty)
@ -52,7 +52,7 @@ object IRSTradeFlow {
val offer = receive<OfferMessage>(replyToParty).unwrap { it } val offer = receive<OfferMessage>(replyToParty).unwrap { it }
// Automatically agree - in reality we'd vet the offer message // Automatically agree - in reality we'd vet the offer message
require(serviceHub.networkMapCache.notaryNodes.map { it.notaryIdentity }.contains(offer.notary)) require(serviceHub.networkMapCache.notaryIdentities.map { it.party }.contains(offer.notary))
send(replyToParty, true) send(replyToParty, true)
subFlow(TwoPartyDealFlow.Acceptor(replyToParty)) subFlow(TwoPartyDealFlow.Acceptor(replyToParty))
} }

View File

@ -61,8 +61,8 @@ object SimmFlow {
@Suspendable @Suspendable
override fun call(): RevisionedState<PortfolioState.Update> { override fun call(): RevisionedState<PortfolioState.Update> {
logger.debug("Calling from: $ourIdentity. Sending to: $otherParty") logger.debug("Calling from: $ourIdentity. Sending to: $otherParty")
require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" } require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" }
notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity notary = serviceHub.networkMapCache.notaryIdentities.first().party // TODO We should pass the notary as a parameter to the flow, not leave it to random choice.
val criteria = LinearStateQueryCriteria(participants = listOf(otherParty)) val criteria = LinearStateQueryCriteria(participants = listOf(otherParty))
val trades = serviceHub.vaultQueryService.queryBy<IRSState>(criteria).states val trades = serviceHub.vaultQueryService.queryBy<IRSState>(criteria).states

View File

@ -1,7 +1,7 @@
package net.corda.vega package net.corda.vega
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.nodeapi.ServiceInfo
import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_BANK_A
import net.corda.testing.DUMMY_BANK_B import net.corda.testing.DUMMY_BANK_B
import net.corda.testing.DUMMY_BANK_C import net.corda.testing.DUMMY_BANK_C

View File

@ -1,7 +1,6 @@
package net.corda.traderdemo package net.corda.traderdemo
import net.corda.client.rpc.CordaRPCClient import net.corda.client.rpc.CordaRPCClient
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.millis import net.corda.core.utilities.millis
import net.corda.finance.DOLLARS import net.corda.finance.DOLLARS
@ -10,6 +9,7 @@ import net.corda.finance.flows.CashPaymentFlow
import net.corda.finance.schemas.CashSchemaV1 import net.corda.finance.schemas.CashSchemaV1
import net.corda.finance.schemas.CommercialPaperSchemaV1 import net.corda.finance.schemas.CommercialPaperSchemaV1
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.BOC import net.corda.testing.BOC

View File

@ -46,12 +46,10 @@ class TraderDemoClientApi(val rpc: CordaRPCOps) {
val ref = OpaqueBytes.of(1) val ref = OpaqueBytes.of(1)
val buyer = rpc.partyFromX500Name(buyerName) ?: throw IllegalStateException("Don't know $buyerName") val buyer = rpc.partyFromX500Name(buyerName) ?: throw IllegalStateException("Don't know $buyerName")
val seller = rpc.partyFromX500Name(sellerName) ?: throw IllegalStateException("Don't know $sellerName") val seller = rpc.partyFromX500Name(sellerName) ?: throw IllegalStateException("Don't know $sellerName")
val notaryLegalIdentity = rpc.partyFromX500Name(DUMMY_NOTARY.name) val notaryIdentity = rpc.notaryIdentities().first().party
?: throw IllegalStateException("Unable to locate ${DUMMY_NOTARY.name} in Network Map Service")
val notaryNode = rpc.nodeIdentityFromParty(notaryLegalIdentity)
?: throw IllegalStateException("Unable to locate notary node in network map cache")
val amounts = calculateRandomlySizedAmounts(amount, 3, 10, Random()) val amounts = calculateRandomlySizedAmounts(amount, 3, 10, Random())
rpc.startFlow(::CashIssueFlow, amount, OpaqueBytes.of(1), notaryNode.notaryIdentity).returnValue.getOrThrow() rpc.startFlow(::CashIssueFlow, amount, OpaqueBytes.of(1), notaryIdentity).returnValue.getOrThrow()
// Pay random amounts of currency up to the requested amount // Pay random amounts of currency up to the requested amount
amounts.forEach { pennies -> amounts.forEach { pennies ->
// TODO This can't be done in parallel, perhaps due to soft-locking issues? // TODO This can't be done in parallel, perhaps due to soft-locking issues?
@ -71,7 +69,7 @@ class TraderDemoClientApi(val rpc: CordaRPCOps) {
} }
// The line below blocks and waits for the future to resolve. // The line below blocks and waits for the future to resolve.
rpc.startFlow(::CommercialPaperIssueFlow, amount, ref, seller, notaryNode.notaryIdentity).returnValue.getOrThrow() rpc.startFlow(::CommercialPaperIssueFlow, amount, ref, seller, notaryIdentity).returnValue.getOrThrow()
println("Commercial paper issued to seller") println("Commercial paper issued to seller")
} }

View File

@ -29,10 +29,11 @@ class BuyerFlow(val otherParty: Party) : FlowLogic<Unit>() {
// Receive the offered amount and automatically agree to it (in reality this would be a longer negotiation) // Receive the offered amount and automatically agree to it (in reality this would be a longer negotiation)
val amount = receive<Amount<Currency>>(otherParty).unwrap { it } val amount = receive<Amount<Currency>>(otherParty).unwrap { it }
val notary: NodeInfo = serviceHub.networkMapCache.notaryNodes[0] require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" }
val notary: Party = serviceHub.networkMapCache.notaryIdentities[0].party
val buyer = TwoPartyTradeFlow.Buyer( val buyer = TwoPartyTradeFlow.Buyer(
otherParty, otherParty,
notary.notaryIdentity, notary,
amount, amount,
CommercialPaper.State::class.java) CommercialPaper.State::class.java)

View File

@ -40,7 +40,7 @@ class SellerFlow(private val otherParty: Party,
override fun call(): SignedTransaction { override fun call(): SignedTransaction {
progressTracker.currentStep = SELF_ISSUING progressTracker.currentStep = SELF_ISSUING
val notary: NodeInfo = serviceHub.networkMapCache.notaryNodes[0] val notary: Party = serviceHub.networkMapCache.notaryIdentities[0].party
val cpOwner = serviceHub.keyManagementService.freshKeyAndCert(ourIdentityAndCert, false) val cpOwner = serviceHub.keyManagementService.freshKeyAndCert(ourIdentityAndCert, false)
val commercialPaper = serviceHub.vaultQueryService.queryBy(CommercialPaper.State::class.java).states.first() val commercialPaper = serviceHub.vaultQueryService.queryBy(CommercialPaper.State::class.java).states.first()
@ -50,7 +50,6 @@ class SellerFlow(private val otherParty: Party,
send(otherParty, amount) send(otherParty, amount)
val seller = TwoPartyTradeFlow.Seller( val seller = TwoPartyTradeFlow.Seller(
otherParty, otherParty,
notary,
commercialPaper, commercialPaper,
amount, amount,
cpOwner, cpOwner,

View File

@ -1,9 +1,9 @@
package net.corda.traderdemo package net.corda.traderdemo
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.node.services.ServiceInfo
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.BOC import net.corda.testing.BOC

View File

@ -3,14 +3,13 @@ package net.corda.testing.driver
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.list import net.corda.core.internal.list
import net.corda.core.node.services.ServiceInfo
import net.corda.core.internal.readLines import net.corda.core.internal.readLines
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_BANK_A
import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.DUMMY_REGULATOR import net.corda.testing.DUMMY_REGULATOR
import net.corda.node.internal.NodeStartup import net.corda.node.internal.NodeStartup
import net.corda.node.services.api.RegulatorService import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.testing.ProjectStructure.projectRootDir import net.corda.testing.ProjectStructure.projectRootDir
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
@ -42,7 +41,7 @@ class DriverTests {
fun `simple node startup and shutdown`() { fun `simple node startup and shutdown`() {
val handles = driver { val handles = driver {
val notary = startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))) val notary = startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
val regulator = startNode(providedName = DUMMY_REGULATOR.name, advertisedServices = setOf(ServiceInfo(RegulatorService.type))) val regulator = startNode(providedName = DUMMY_REGULATOR.name)
listOf(nodeMustBeUp(notary), nodeMustBeUp(regulator)) listOf(nodeMustBeUp(notary), nodeMustBeUp(regulator))
} }
handles.map { nodeMustBeDown(it) } handles.map { nodeMustBeDown(it) }

View File

@ -24,6 +24,7 @@ import net.corda.testing.node.MockAttachmentStorage
import net.corda.testing.node.MockNetworkMapCache import net.corda.testing.node.MockNetworkMapCache
import net.corda.testing.node.MockStateMachineRecordedTransactionMappingStorage import net.corda.testing.node.MockStateMachineRecordedTransactionMappingStorage
import net.corda.testing.node.MockTransactionStorage import net.corda.testing.node.MockTransactionStorage
import java.security.PublicKey
import java.sql.Connection import java.sql.Connection
import java.time.Clock import java.time.Clock
@ -67,6 +68,8 @@ open class MockServiceHubInternal(
get() = overrideClock ?: throw UnsupportedOperationException() get() = overrideClock ?: throw UnsupportedOperationException()
override val myInfo: NodeInfo override val myInfo: NodeInfo
get() = NodeInfo(listOf(MOCK_HOST_AND_PORT), listOf(DUMMY_IDENTITY_1), 1, serial = 1L) // Required to get a dummy platformVersion when required for tests. get() = NodeInfo(listOf(MOCK_HOST_AND_PORT), listOf(DUMMY_IDENTITY_1), 1, serial = 1L) // Required to get a dummy platformVersion when required for tests.
override val notaryIdentityKey: PublicKey
get() = throw IllegalStateException("No notary identity in MockServiceHubInternal")
override val monitoringService: MonitoringService = MonitoringService(MetricRegistry()) override val monitoringService: MonitoringService = MonitoringService(MetricRegistry())
override val rpcFlows: List<Class<out FlowLogic<*>>> override val rpcFlows: List<Class<out FlowLogic<*>>>
get() = throw UnsupportedOperationException() get() = throw UnsupportedOperationException()

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