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

View File

@ -7,8 +7,8 @@ import javafx.collections.FXCollections
import javafx.collections.ObservableList
import net.corda.client.jfx.utils.fold
import net.corda.client.jfx.utils.map
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.NodeInfo
import net.corda.core.node.services.NetworkMapCache.MapChange
import java.security.PublicKey
@ -33,25 +33,13 @@ class NetworkIdentityModel {
private val identityCache = CacheBuilder.newBuilder()
.build<PublicKey, ObservableValue<NodeInfo?>>(CacheLoader.from {
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<NodeInfo> = networkIdentities.filtered { it.advertisedServices.any { it.info.type.isNotary() } }
val myNodeInfo = rpcProxy.map { it?.nodeInfo() } // TODO Used only for querying for advertised services, remove with services.
val myIdentity = myNodeInfo.map { it?.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() }
}
val notaries: ObservableList<PartyAndCertificate> = FXCollections.observableList(rpcProxy.value?.notaryIdentities())
val notaryNodes: ObservableList<NodeInfo> = FXCollections.observableList(notaries.map { rpcProxy.value?.nodeInfoFromParty(it.party) })
val parties: ObservableList<NodeInfo> = networkIdentities.filtered { it.legalIdentitiesAndCerts.all { it !in notaries } }
val myIdentity = rpcProxy.map { it?.nodeInfo()?.legalIdentitiesAndCerts?.first()?.party }
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.core.contracts.ContractState
import net.corda.core.flows.StateMachineRunId
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.messaging.*
import net.corda.core.node.services.NetworkMapCache.MapChange
import net.corda.core.node.services.Vault
@ -45,6 +46,7 @@ class NodeMonitorModel {
val networkMap: Observable<MapChange> = networkMapSubject
val proxyObservable = SimpleObjectProperty<CordaRPCOps?>()
lateinit var notaryIdentities: List<PartyAndCertificate>
/**
* Register for updates to/from a given vault.
@ -60,6 +62,7 @@ class NodeMonitorModel {
)
val connection = client.start(username, password)
val proxy = connection.proxy
notaryIdentities = proxy.notaryIdentities()
val (stateMachines, stateMachineUpdates) = proxy.stateMachinesFeed()
// 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.messaging.CordaRPCOps;
import net.corda.core.messaging.FlowHandle;
import net.corda.core.node.services.ServiceInfo;
import net.corda.core.utilities.OpaqueBytes;
import net.corda.finance.flows.AbstractCashFlow;
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.StartedNode;
import net.corda.node.services.transactions.ValidatingNotaryService;
import net.corda.nodeapi.ServiceInfo;
import net.corda.nodeapi.User;
import net.corda.testing.CoreTestUtils;
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.startFlow
import net.corda.core.messaging.startTrackedFlow
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
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.StartedNode
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.nodeapi.User
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.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.NodeInfo
import net.corda.core.node.services.NetworkMapCache
import net.corda.core.node.services.Vault
@ -212,6 +213,11 @@ interface CordaRPCOps : RPCOps {
*/
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
*/
@ -284,11 +290,11 @@ interface CordaRPCOps : RPCOps {
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.
*/
fun nodeIdentityFromParty(party: AbstractParty): NodeInfo?
fun nodeInfoFromParty(party: AbstractParty): NodeInfo?
/**
* 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.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.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.
* @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.
@CordaSerializable
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 platformVersion: Int,
val advertisedServices: List<ServiceEntry> = emptyList(),
val serial: Long
) {
init {
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
val legalIdentities: List<Party> get() {
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. */
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
* 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].
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.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.randomOrNull
import net.corda.core.messaging.DataFeed
import net.corda.core.node.NodeInfo
import net.corda.core.node.ServiceEntry
import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.NetworkHostAndPort
import rx.Observable
@ -31,18 +31,9 @@ interface NetworkMapCache {
data class Modified(override val node: NodeInfo, val previousNode: NodeInfo) : MapChange()
}
/** A list of all nodes the cache is aware of */
val partyNodes: List<NodeInfo>
/** A list of nodes that advertise a network map service */
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)
/** A list of notary services available on the network */
// TODO this list will be taken from NetworkParameters distributed by NetworkMap.
val notaryIdentities: List<PartyAndCertificate>
/** Tracks changes to the network map cache */
val changed: Observable<MapChange>
/** Future to track completion of the NetworkMapService registration. */
@ -54,26 +45,6 @@ interface NetworkMapCache {
*/
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
* 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?
/** 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. */
fun getNodeByAddress(address: NetworkHostAndPort): NodeInfo?
fun getPeerByLegalName(principal: CordaX500Name): Party? = getNodeByLegalName(principal)?.let {
it.legalIdentitiesAndCerts.singleOrNull { it.name == principal }?.party
fun getPeerByLegalName(name: CordaX500Name): Party? = getNodeByLegalName(name)?.let {
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
* the services it provides. In case of a distributed service run by multiple nodes each participant advertises
* the identity of the *whole group*.
*/
/** Look up the node infos for a specific peer key. */
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 */
fun getPartyInfo(party: Party): PartyInfo?
/** Gets a notary identity by the given name. */
fun getNotary(principal: CordaX500Name): Party? {
val notaryNode = notaryNodes.filter {
it.advertisedServices.any { it.info.type.isSubTypeOf(ServiceType.notary) && it.info.name == principal }
}.randomOrNull()
return notaryNode?.notaryIdentity
}
fun getNotary(name: CordaX500Name): Party? = notaryIdentities.firstOrNull { it.name == name }?.party
/**
* 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)
*/
fun getAnyNotary(type: ServiceType? = null): 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;
}
fun getAnyNotary(): Party? = notaryIdentities.randomOrNull()?.party
/** 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 {
val notary = notaryNodes.firstOrNull { it.notaryIdentity == party }
?: throw IllegalArgumentException("No notary found with identity $party. This is most likely caused " +
"by using the notary node's legal identity instead of its advertised notary identity. " +
"Your options are: ${notaryNodes.map { "\"${it.notaryIdentity.name}\"" }.joinToString()}.")
return notary.advertisedServices.any { it.info.type.isValidatingNotary() }
val notary = notaryIdentities.firstOrNull { it.party == party } ?:
throw IllegalArgumentException("No notary found with identity $party.")
return !notary.name.toString().contains("corda.notary.simple", true) // TODO This implementation will change after introducing of NetworkParameters.
}
/**
* 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.node.NodeInfo
import net.corda.core.node.ServiceEntry
import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize
import net.corda.core.utilities.NetworkHostAndPort
@ -39,10 +38,6 @@ object NodeInfoSchemaV1 : MappedSchema(
@Column(name = "platform_version")
val platformVersion: Int,
@Column(name = "advertised_services")
@ElementCollection
var advertisedServices: List<DBServiceEntry> = emptyList(),
/**
* 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
@ -56,9 +51,6 @@ object NodeInfoSchemaV1 : MappedSchema(
this.addresses.map { it.toHostAndPort() },
(this.legalIdentitiesAndCerts.filter { it.isMain } + this.legalIdentitiesAndCerts.filter { !it.isMain }).map { it.toLegalIdentityAndCert() },
this.platformVersion,
this.advertisedServices.map {
it.serviceEntry?.deserialize<ServiceEntry>() ?: throw IllegalStateException("Service entry shouldn't be null")
},
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).
*/

View File

@ -8,9 +8,9 @@ import net.corda.core.identity.Party
import net.corda.core.internal.FetchAttachmentsFlow
import net.corda.core.internal.FetchDataFlow
import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.network.NetworkMapService
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.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.contracts.DummyContract
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockServices
import org.junit.After
@ -39,8 +40,8 @@ class CollectSignaturesFlowTests {
a = nodes.partyNodes[0]
b = nodes.partyNodes[1]
c = nodes.partyNodes[2]
notary = nodes.notaryNode.info.notaryIdentity
mockNet.runNetwork()
notary = a.services.getDefaultNotary()
a.internals.ensureRegistered()
}
@ -86,7 +87,7 @@ class CollectSignaturesFlowTests {
@Suspendable
override fun call(): SignedTransaction {
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 myKeys = myInputKeys + (identities[ourIdentity] ?: ourIdentity).owningKey
@ -107,7 +108,7 @@ class CollectSignaturesFlowTests {
class Initiator(val state: DummyContract.MultiOwnerState) : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
val notary = serviceHub.networkMapCache.notaryNodes.single().notaryIdentity
val notary = serviceHub.getDefaultNotary()
val myInputKeys = state.participants.map { it.owningKey }
val command = Command(DummyContract.Commands.Create(), myInputKeys)
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.contracts.DummyContract
import net.corda.testing.contracts.DummyContractV2
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork
import net.corda.testing.rpcDriver
import net.corda.testing.rpcTestUser
@ -54,9 +55,8 @@ class ContractUpgradeFlowTest {
mockNet.runNetwork()
a.internals.ensureRegistered()
notary = nodes.notaryNode.info.notaryIdentity
val nodeIdentity = nodes.notaryNode.info.legalIdentitiesAndCerts.single { it.party == nodes.notaryNode.info.notaryIdentity }
notary = a.services.getDefaultNotary()
val nodeIdentity = nodes.notaryNode.info.legalIdentitiesAndCerts.single { it.party == notary }
a.database.transaction {
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.node.internal.StartedNode
import net.corda.testing.chooseIdentity
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockServices
import org.junit.After
@ -31,9 +32,9 @@ class FinalityFlowTests {
val nodes = mockNet.createSomeNodes(2)
nodeA = nodes.partyNodes[0]
nodeB = nodes.partyNodes[1]
notary = nodes.notaryNode.info.notaryIdentity
mockNet.runNetwork()
nodeA.internals.ensureRegistered()
notary = nodeA.services.getDefaultNotary()
}
@After

View File

@ -13,6 +13,7 @@ import net.corda.testing.ALICE
import net.corda.testing.BOB
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.chooseIdentity
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork
import org.junit.After
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
val anonymous = true
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 confidentialIdentity = issueTx.tx.outputs.map { it.data }.filterIsInstance<Cash.State>().single().owner
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.node.internal.StartedNode
import net.corda.testing.chooseIdentity
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockServices
import org.junit.After
@ -32,9 +33,9 @@ class ManualFinalityFlowTests {
nodeA = nodes.partyNodes[0]
nodeB = nodes.partyNodes[1]
nodeC = nodes.partyNodes[2]
notary = nodes.notaryNode.info.notaryIdentity
mockNet.runNetwork()
nodeA.internals.ensureRegistered()
notary = nodeA.services.getDefaultNotary()
}
@After

View File

@ -17,6 +17,7 @@ import net.corda.testing.MEGA_CORP_KEY
import net.corda.testing.MINI_CORP
import net.corda.testing.chooseIdentity
import net.corda.testing.contracts.DummyContract
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockServices
import org.junit.After
@ -47,8 +48,8 @@ class ResolveTransactionsFlowTest {
b = nodes.partyNodes[1]
a.internals.registerInitiatedFlow(TestResponseFlow::class.java)
b.internals.registerInitiatedFlow(TestResponseFlow::class.java)
notary = nodes.notaryNode.info.notaryIdentity
mockNet.runNetwork()
notary = a.services.getDefaultNotary()
}
@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.FetchDataFlow
import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.unwrap
import net.corda.node.internal.InitiatedFlowFactory
import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.persistence.NodeAttachmentService

View File

@ -6,6 +6,19 @@ from the previous milestone release.
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
* ``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.messaging.startFlow
import net.corda.core.messaging.vaultTrackBy
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.Vault
import net.corda.core.utilities.OpaqueBytes
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.CashPaymentFlow
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.nodeapi.User
import net.corda.testing.*
@ -56,11 +56,12 @@ class IntegrationTestingTutorial {
// START 4
val issueRef = OpaqueBytes.of(0)
val notaryParty = aliceProxy.notaryIdentities().first().party
(1..10).map { i ->
aliceProxy.startFlow(::CashIssueFlow,
i.DOLLARS,
issueRef,
notary.nodeInfo.notaryIdentity
notaryParty
).returnValue
}.transpose().getOrThrow()
// 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.Party;
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.Page;
import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria;
@ -54,11 +53,13 @@ public class FlowCookbookJava {
private final boolean arg1;
private final int arg2;
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.arg2 = arg2;
this.counterparty = counterparty;
this.regulator = regulator;
}
/*----------------------------------
@ -124,11 +125,11 @@ public class FlowCookbookJava {
// We retrieve a notary from the network map.
// DOCSTART 1
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
// ``List<NodeInfo>``. We have to extract the notary identity of
// the node we want.
Party firstNotary = getServiceHub().getNetworkMapCache().getNotaryNodes().get(0).getNotaryIdentity();
Party firstNotary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0).getParty();
// DOCEND 1
// We may also need to identify a specific counterparty.
@ -138,12 +139,6 @@ public class FlowCookbookJava {
Party keyedCounterparty = getServiceHub().getIdentityService().partyFromKey(dummyPubKey);
// 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 *
------------------------------*/
@ -528,7 +523,7 @@ public class FlowCookbookJava {
// We can also choose to send it to additional parties who aren't one
// of the state's participants.
// 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);
// 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.vaultQueryBy
import net.corda.core.node.CordaPluginRegistry
import net.corda.core.node.services.ServiceInfo
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializationCustomization
import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
import net.corda.finance.USD
import net.corda.finance.contracts.asset.Cash
import net.corda.finance.flows.CashExitFlow
import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.nodeapi.User
import net.corda.testing.ALICE
@ -56,6 +57,7 @@ fun main(args: Array<String>) {
// START 2
val client = node.rpcClientToNode()
val proxy = client.start("user", "password").proxy
proxy.waitUntilNetworkReady().getOrThrow()
thread {
generateTransactions(proxy)
@ -111,8 +113,7 @@ fun generateTransactions(proxy: CordaRPCOps) {
sum + state.state.data.amount.quantity
}
val issueRef = OpaqueBytes.of(0)
val parties = proxy.networkMapSnapshot()
val notary = parties.first { it.advertisedServices.any { it.info.type.isNotary() } }.notaryIdentity
val notary = proxy.notaryIdentities().first().party
val me = proxy.nodeInfo().legalIdentities.first()
while (true) {
Thread.sleep(1000)

View File

@ -49,7 +49,7 @@ class MyValidatingNotaryFlow(otherSide: Party, service: MyCustomValidatingNotary
private fun checkSignatures(stx: SignedTransaction) {
try {
stx.verifySignaturesExcept(serviceHub.myInfo.notaryIdentity.owningKey)
stx.verifySignaturesExcept(serviceHub.notaryIdentityKey)
} catch (e: SignatureException) {
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.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow
import net.corda.testing.getDefaultNotary
import java.util.*
// DOCSTART CustomVaultQuery
@ -132,7 +133,7 @@ object TopupIssuerFlow {
issueTo: Party,
issuerPartyRef: OpaqueBytes): AbstractCashFlow.Result {
// 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
progressTracker.currentStep = ISSUING
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.Party
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.queryBy
import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria
@ -40,7 +39,7 @@ object FlowCookbook {
@StartableByRPC
// Every flow must subclass ``FlowLogic``. The generic indicates the
// 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 *
@ -109,22 +108,18 @@ object FlowCookbook {
// Unlike the first two methods, ``getNotaryNodes`` returns a
// ``List<NodeInfo>``. We have to extract the notary identity of
// the node we want.
val firstNotary: Party = serviceHub.networkMapCache.notaryNodes[0].notaryIdentity
val firstNotary: Party = serviceHub.networkMapCache.notaryIdentities[0].party
// DOCEND 1
// We may also need to identify a specific counterparty. We
// do so using identity service.
// DOCSTART 2
val namedCounterparty: Party? = serviceHub.identityService.partyFromX500Name(CordaX500Name(organisation = "NodeA", locality = "London", country = "UK"))
val keyedCounterparty: Party? = serviceHub.identityService.partyFromKey(dummyPubKey)
val namedCounterparty: Party = serviceHub.identityService.partyFromX500Name(CordaX500Name(organisation = "NodeA", locality = "London", country = "UK")) ?:
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
// 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 *
-----------------------------**/

View File

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

View File

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

View File

@ -4,12 +4,12 @@ import net.corda.core.contracts.LinearState
import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.UniqueIdentifier
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.vault.QueryCriteria
import net.corda.core.toFuture
import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.transactions.ValidatingNotaryService
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) {
TwoPartyTradeFlow.Buyer(
it,
notary = services.networkMapCache.notaryNodes[0].notaryIdentity,
notary = services.networkMapCache.notaryIdentities[0].party,
acceptablePrice = TODO(),
typeToBuy = TODO())
}

View File

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

View File

@ -11,8 +11,6 @@ import net.corda.core.flows.FlowLogic
import net.corda.core.flows.SignTransactionFlow
import net.corda.core.identity.AnonymousParty
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.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder
@ -51,7 +49,7 @@ object TwoPartyDealFlow {
}
abstract val payload: Any
abstract val notaryNode: NodeInfo
abstract val notaryParty: Party
abstract val otherParty: Party
@Suspendable override fun call(): SignedTransaction {
@ -82,7 +80,8 @@ object TwoPartyDealFlow {
/**
* 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 {
object RECEIVING : ProgressTracker.Step("Waiting for deal info.")
@ -126,12 +125,10 @@ object TwoPartyDealFlow {
logger.trace { "Recorded transaction." }
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
// just for demo purposes.
regulators.forEach { send(it.serviceIdentities(ServiceType.regulator).first(), ftx) }
}
// Copy the transaction to every regulator in the network. This is obviously completely bogus, it's
// just for demo purposes.
regulators.forEach { send(it, ftx) }
progressTracker.currentStep = COPYING_TO_COUNTERPARTY
// Send the final transaction hash back to the other party.
@ -173,8 +170,7 @@ object TwoPartyDealFlow {
open class Instigator(override val otherParty: Party,
override val payload: AutoOffer,
override val progressTracker: ProgressTracker = Primary.tracker()) : Primary() {
override val notaryNode: NodeInfo get() =
serviceHub.networkMapCache.notaryNodes.single { it.notaryIdentity == payload.notary }
override val notaryParty: Party get() = payload.notary
@Suspendable override fun checkProposal(stx: SignedTransaction) = requireThat {
// Add some constraints here.

View File

@ -56,7 +56,6 @@ object TwoPartyTradeFlow {
)
open class Seller(val otherParty: Party,
val notaryNode: NodeInfo,
val assetToSell: StateAndRef<OwnableState>,
val price: Amount<Currency>,
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.node.internal.StartedNode
import net.corda.testing.chooseIdentity
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.MockNode
@ -31,10 +32,10 @@ class CashExitFlowTests {
val nodes = mockNet.createSomeNodes(1)
notaryNode = nodes.notaryNode
bankOfCordaNode = nodes.partyNodes[0]
notary = notaryNode.info.notaryIdentity
bankOfCorda = bankOfCordaNode.info.chooseIdentity()
mockNet.runNetwork()
notary = bankOfCordaNode.services.getDefaultNotary()
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary)).resultFuture
mockNet.runNetwork()
future.getOrThrow()

View File

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

View File

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

View File

@ -1,4 +1,4 @@
package net.corda.core.node.services
package net.corda.nodeapi
import net.corda.core.serialization.CordaSerializable
@ -27,15 +27,8 @@ class ServiceType private constructor(val id: String) {
}
val notary: ServiceType = corda.getSubType("notary")
val regulator: ServiceType = corda.getSubType("regulator")
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)
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 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 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.StartableByRPC
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.testing.ALICE
import net.corda.node.internal.NodeStartup
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.testing.driver.ListenProcessDeathException
import net.corda.testing.driver.NetworkMapStartStrategy
@ -18,6 +18,7 @@ import net.corda.testing.ProjectStructure.projectRootDir
import net.corda.testing.driver.driver
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Ignore
import org.junit.Test
import java.io.*
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
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)) {
val future = startNode(providedName = ALICE.name, advertisedServices = tooManyAdvertisedServices)
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.internal.concurrent.transpose
import net.corda.core.messaging.startFlow
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.minutes
import net.corda.finance.DOLLARS
import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User
import net.corda.testing.chooseIdentity
@ -110,9 +110,10 @@ class NodePerformanceTests {
a as NodeHandle.InProcess
val metricRegistry = startReporter(shutdownManager, a.node.services.monitoringService.metrics)
a.rpcClientToNode().use("A", "A") { connection ->
val notary = connection.proxy.notaryIdentities().first().party
println("ISSUING")
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()
doneFutures.transpose().get()
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.Party
import net.corda.core.internal.div
import net.corda.core.node.services.ServiceInfo
import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder
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.minCorrectReplicas
import net.corda.node.utilities.ServiceIdentityGenerator
import net.corda.nodeapi.ServiceInfo
import net.corda.testing.chooseIdentity
import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.contracts.DummyContract
import net.corda.testing.dummyCommand
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork
import org.junit.After
import org.junit.Test
@ -47,7 +48,7 @@ class BFTNotaryServiceTests {
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?
val replicaIds = (0 until clusterSize)
val party = ServiceIdentityGenerator.generateToDisk(
@ -66,13 +67,14 @@ class BFTNotaryServiceTests {
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. */
@Test
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 trivialTx = signInitialTransaction(notary) {
addOutputState(DummyContract.SingleOwnerState(owner = info.chooseIdentity()), DUMMY_PROGRAM_ID)
@ -96,7 +98,8 @@ class BFTNotaryServiceTests {
private fun detectDoubleSpend(faultyReplicas: Int) {
val clusterSize = minClusterSize(faultyReplicas)
val notary = bftNotaryCluster(clusterSize)
bftNotaryCluster(clusterSize)
val notary = node.services.getDefaultNotary()
node.run {
val issueTx = signInitialTransaction(notary) {
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.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.bufferUntilSubscribed
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.StateMachineUpdate
@ -51,14 +50,9 @@ class DistributedServiceTests : DriverBasedTest() {
raftNotaryIdentity = notaryIdentity
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)
// 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
fun connectRpc(node: NodeHandle): CordaRPCOps {
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.messaging.MessageRecipients
import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.services.ServiceInfo
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.deserialize
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.SimpleNotaryService
import net.corda.node.utilities.ServiceIdentityGenerator
import net.corda.nodeapi.ServiceInfo
import net.corda.testing.*
import net.corda.testing.node.NodeBasedTest
import org.assertj.core.api.Assertions.assertThat
@ -84,7 +84,8 @@ class P2PMessagingTest : NodeBasedTest() {
startNode(ALICE.name)
).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

View File

@ -8,7 +8,6 @@ import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party
import net.corda.core.messaging.startFlow
import net.corda.core.node.services.ServiceInfo
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
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.getOrThrow
import net.corda.node.services.FlowPermissions
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User
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.node.CordaPluginRegistry
import net.corda.core.node.NodeInfo
import net.corda.core.node.ServiceEntry
import net.corda.core.node.ServiceHub
import net.corda.core.node.services.*
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.services.NotaryChangeHandler
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.config.NodeConfiguration
import net.corda.node.services.config.configureWithDevSSLCertificate
@ -75,6 +76,7 @@ import java.lang.reflect.InvocationTargetException
import java.nio.file.Path
import java.security.KeyPair
import java.security.KeyStoreException
import java.security.PublicKey
import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate
import java.sql.Connection
@ -134,8 +136,9 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
protected val services: ServiceHubInternal get() = _services
private lateinit var _services: ServiceHubInternalImpl
lateinit var legalIdentity: PartyAndCertificate
protected lateinit var legalIdentity: PartyAndCertificate
protected lateinit var info: NodeInfo
protected var myNotaryIdentity: PartyAndCertificate? = null
protected lateinit var checkpointStorage: CheckpointStorage
protected lateinit var smm: StateMachineManager
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.transactionVerifierService, services.validatedTransactions, services.contractUpgradeService,
services, this)
makeAdvertisedServices(tokenizableServices)
makeNetworkServices(tokenizableServices)
return tokenizableServices
}
@ -414,22 +417,21 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
}
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)
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.
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
* 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> {
return advertisedServices.map {
val identity = obtainIdentity(it)
ServiceEntry(it, identity)
}
protected open fun getNotaryIdentity(): PartyAndCertificate? {
return advertisedServices.singleOrNull { it.type.isNotary() }?.let { obtainIdentity(it) }
}
@VisibleForTesting
@ -478,8 +480,8 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
}
}
private fun makeAdvertisedServices(tokenizableServices: MutableList<Any>) {
val serviceTypes = info.advertisedServices.map { it.info.type }
private fun makeNetworkServices(tokenizableServices: MutableList<Any>) {
val serviceTypes = advertisedServices.map { it.type }
inNodeNetworkMapService = if (NetworkMapService.type in serviceTypes) makeNetworkMapService() else NullNetworkMapService
val notaryServiceType = serviceTypes.singleOrNull { it.isNotary() }
if (notaryServiceType != null) {
@ -584,7 +586,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
.filterNotNull()
.toTypedArray()
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 ->
// TODO how should we handle network map removal
if (mapChange is MapChange.Added) {
@ -628,7 +630,12 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
// Create node identity if service info = null
Pair("identity", myLegalName.copy(commonName = null))
} 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)
}
@ -728,6 +735,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
override val myInfo: NodeInfo get() = info
override val database: CordaPersistence get() = this@AbstractNode.database
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 {
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.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.messaging.*
import net.corda.core.node.NodeInfo
import net.corda.core.node.services.NetworkMapCache
@ -114,6 +115,10 @@ class CordaRPCOpsImpl(
return services.myInfo
}
override fun notaryIdentities(): List<PartyAndCertificate> {
return services.networkMapCache.notaryIdentities
}
override fun addVaultTransactionNote(txnId: SecureHash, txnNote: String) {
return database.transaction {
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 {
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.messaging.RPCOps
import net.corda.core.node.ServiceHub
import net.corda.core.node.services.ServiceInfo
import net.corda.core.serialization.SerializationDefaults
import net.corda.core.utilities.*
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.services.RPCUserService
import net.corda.node.services.RPCUserServiceImpl
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.config.FullNodeConfiguration
import net.corda.node.services.messaging.ArtemisMessagingServer
import net.corda.node.services.messaging.ArtemisMessagingServer.Companion.ipDetectRequestProperty

View File

@ -5,9 +5,9 @@ import com.typesafe.config.ConfigException
import joptsimple.OptionException
import net.corda.core.internal.*
import net.corda.core.internal.concurrent.thenMatch
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.loggerFor
import net.corda.node.*
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.config.FullNodeConfiguration
import net.corda.node.services.transactions.bftSMaRtSerialFilter
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.StartableByRPC
import net.corda.core.internal.*
import net.corda.core.node.NodeInfo
import net.corda.core.node.CordaPluginRegistry
import net.corda.core.node.services.CordaService
import net.corda.core.node.services.ServiceType
import net.corda.core.schemas.MappedSchema
import net.corda.core.serialization.SerializeAsToken
import net.corda.core.utilities.debug
import net.corda.core.utilities.loggerFor
import net.corda.node.internal.classloading.requireAnnotation
import java.lang.reflect.Modifier
@ -23,9 +20,7 @@ import java.net.URI
import java.net.URL
import java.net.URLClassLoader
import java.nio.file.Path
import java.nio.file.Paths
import java.util.*
import java.util.stream.Collectors
import kotlin.reflect.KClass
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
val isNotary = serviceHub.networkMapCache.notaryNodes.any { it.notaryIdentity == newNotary }
val isNotary = serviceHub.networkMapCache.isNotary(newNotary)
if (!isNotary) {
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
import net.corda.core.identity.CordaX500Name
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.node.internal.NetworkMapInfo
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.messaging.CertificateChainCheckPolicy
import net.corda.node.services.network.NetworkMapService
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.services.KeyManagementService
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.SerializedBytes
import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize
import net.corda.core.utilities.debug
import net.corda.core.utilities.loggerFor
import net.corda.nodeapi.ServiceType
import net.corda.node.services.api.AbstractNodeService
import net.corda.node.services.api.ServiceHubInternal
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.createMessage
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.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.VisibleForTesting
import net.corda.core.internal.bufferUntilSubscribed
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
// 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())
override val partyNodes: MutableList<NodeInfo> get() = registeredNodes.map { it.value }.toMutableList()
override val networkMapNodes: List<NodeInfo> get() = getNodesWithService(NetworkMapService.type)
protected val partyNodes: MutableList<NodeInfo> get() = registeredNodes.map { it.value }.toMutableList()
private val _changed = PublishSubject.create<MapChange>()
// We use assignment here so that multiple subscribers share the same wrapped Observable.
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
private var _loadDBSuccess: Boolean = false
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 {
serviceHub.database.transaction { loadFromDB() }
@ -80,8 +89,8 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
return PartyInfo.SingleNode(party, nodes[0].addresses)
}
for (node in nodes) {
for (service in node.advertisedServices) {
if (service.identity.party == party) {
for (identity in node.legalIdentities) {
if (identity == party) {
return PartyInfo.DistributedNode(party)
}
}
@ -89,9 +98,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
return null
}
// TODO See comment to queryByLegalName why it's left like that.
override fun getNodeByLegalName(principal: CordaX500Name): NodeInfo? = partyNodes.singleOrNull { principal in it.legalIdentities.map { it.name } }
//serviceHub!!.database.transaction { queryByLegalName(principal).firstOrNull() }
override fun getNodeByLegalName(name: CordaX500Name): NodeInfo? = serviceHub.database.transaction { queryByLegalName(name).firstOrNull() }
override fun getNodesByLegalIdentityKey(identityKey: PublicKey): List<NodeInfo> =
serviceHub.database.transaction { queryByIdentityKey(identityKey) }
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) {
// TODO: Implement filtering by sequence number, so we only accept changes that are
// 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)
serviceHub.database.dataSource.connection.use {
val session = serviceHub.database.entityManagerFactory.withOptions().connection(it.apply {
transactionIsolation = 1
}).openSession()
transactionIsolation = 1
}).openSession()
session.use {
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?
@ -322,7 +335,6 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
legalIdentitiesAndCerts = nodeInfo.legalIdentitiesAndCerts.mapIndexed { idx, elem ->
NodeInfoSchemaV1.DBPartyAndCertificate(elem, isMain = idx == 0) },
platformVersion = nodeInfo.platformVersion,
advertisedServices = nodeInfo.advertisedServices.map { NodeInfoSchemaV1.DBServiceEntry(it.serialize().bytes) },
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.identity.Party
import net.corda.core.node.services.ServiceType
import net.corda.core.node.services.TimeWindowChecker
import net.corda.core.node.services.TrustedAuthorityNotaryService
import net.corda.nodeapi.ServiceType
import net.corda.node.services.api.ServiceHubInternal
/** 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) {
try {
stx.verifySignaturesExcept(serviceHub.myInfo.notaryIdentity.owningKey)
stx.verifySignaturesExcept(serviceHub.notaryIdentityKey)
} catch(e: SignatureException) {
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.identity.Party
import net.corda.core.node.services.ServiceType
import net.corda.core.node.services.TimeWindowChecker
import net.corda.core.node.services.TrustedAuthorityNotaryService
import net.corda.nodeapi.ServiceType
import net.corda.node.services.api.ServiceHubInternal
/** 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.StartableByRPC
import net.corda.core.flows.StateMachineRunId
import net.corda.core.identity.Party
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.queryBy
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.network.NetworkMapService
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.PermissionException
import net.corda.nodeapi.User
@ -59,6 +60,7 @@ class CordaRPCOpsImplTest {
lateinit var mockNet: MockNetwork
lateinit var aliceNode: StartedNode<MockNode>
lateinit var notaryNode: StartedNode<MockNode>
lateinit var notary: Party
lateinit var rpc: CordaRPCOps
lateinit var stateMachineUpdates: Observable<StateMachineUpdate>
lateinit var transactions: Observable<SignedTransaction>
@ -78,6 +80,7 @@ class CordaRPCOpsImplTest {
mockNet.runNetwork()
networkMap.internals.ensureRegistered()
notary = rpc.notaryIdentities().first().party
}
@After
@ -102,7 +105,7 @@ class CordaRPCOpsImplTest {
// Tell the monitoring service node to issue some cash
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()
var issueSmId: StateMachineRunId? = null
@ -146,7 +149,7 @@ class CordaRPCOpsImplTest {
val result = rpc.startFlow(::CashIssueFlow,
100.DOLLARS,
OpaqueBytes(ByteArray(1, { 1 })),
notaryNode.info.notaryIdentity
notary
)
mockNet.runNetwork()
@ -196,7 +199,7 @@ class CordaRPCOpsImplTest {
val signaturePubKeys = stx.sigs.map { it.by }.toSet()
// Alice and Notary signed
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`() {
CURRENT_RPC_CONTEXT.set(RpcContext(User("user", "pwd", permissions = emptySet())))
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
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.TopicStringValidator
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.SingleMessageRecipient
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.serialization.CordaSerializable
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.Seller
import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.api.WritableTransactionStorage
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.persistence.DBTransactionStorage
@ -99,23 +98,25 @@ class TwoPartyTradeFlowTests {
val bankNode = basketOfNodes.partyNodes[2]
val cashIssuer = bankNode.info.chooseIdentity().ref(1)
val cpIssuer = bankNode.info.chooseIdentity().ref(1, 2, 3)
val notary = aliceNode.services.getDefaultNotary()
aliceNode.internals.disableDBCloseOnStop()
bobNode.internals.disableDBCloseOnStop()
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)
}
val alicesFakePaper = aliceNode.database.transaction {
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)
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notaryNode, aliceNode, bobNode,
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, aliceNode, bobNode,
"alice's paper".outputStateAndRef())
// 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 bankNode = mockNet.createPartyNode(notaryNode.network.myAddress, BOC.name)
val issuer = bankNode.info.chooseIdentity().ref(1)
val notary = aliceNode.services.getDefaultNotary()
aliceNode.internals.disableDBCloseOnStop()
bobNode.internals.disableDBCloseOnStop()
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)
}
val alicesFakePaper = aliceNode.database.transaction {
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)
@ -171,7 +173,7 @@ class TwoPartyTradeFlowTests {
}
}
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notaryNode, aliceNode, bobNode,
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, aliceNode, bobNode,
"alice's paper".outputStateAndRef())
assertEquals(aliceResult.getOrThrow(), bobStateMachine.getOrThrow().resultFuture.getOrThrow())
@ -216,17 +218,18 @@ class TwoPartyTradeFlowTests {
val networkMapAddress = notaryNode.network.myAddress
mockNet.runNetwork() // Clear network map registration messages
val notary = aliceNode.services.getDefaultNotary()
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)
}
val alicesFakePaper = aliceNode.database.transaction {
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)
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.
// 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 bankNode = makeNodeWithTracking(notaryNode.network.myAddress, BOC.name)
val issuer = bankNode.info.chooseIdentity().ref(1, 2, 3)
mockNet.runNetwork()
notaryNode.internals.ensureRegistered()
val notary = aliceNode.services.getDefaultNotary()
mockNet.registerIdentities()
@ -352,17 +355,17 @@ class TwoPartyTradeFlowTests {
}
val bobsFakeCash = fillUpForBuyer(false, issuer, AnonymousParty(bobNode.info.chooseIdentity().owningKey),
notaryNode.info.notaryIdentity).second
notary).second
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bankNode)
val alicesFakePaper = aliceNode.database.transaction {
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)
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()
@ -441,6 +444,7 @@ class TwoPartyTradeFlowTests {
mockNet.runNetwork()
notaryNode.internals.ensureRegistered()
val notary = aliceNode.services.getDefaultNotary()
mockNet.registerIdentities()
@ -458,12 +462,12 @@ class TwoPartyTradeFlowTests {
val bobsKey = bobNode.services.keyManagementService.keys.single()
val bobsFakeCash = fillUpForBuyer(false, issuer, AnonymousParty(bobsKey),
notaryNode.info.notaryIdentity).second
notary).second
insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bankNode)
val alicesFakePaper = aliceNode.database.transaction {
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)
@ -474,7 +478,7 @@ class TwoPartyTradeFlowTests {
val aliceTxMappings = with(aliceNode) {
database.transaction { services.stateMachineRecordedTransactionMapping.track().updates }
}
val aliceSmId = runBuyerAndSeller(notaryNode, aliceNode, bobNode,
val aliceSmId = runBuyerAndSeller(notary, aliceNode, bobNode,
"alice's paper".outputStateAndRef()).sellerId
mockNet.runNetwork()
@ -533,21 +537,21 @@ class TwoPartyTradeFlowTests {
val sellerId: StateMachineRunId
)
private fun runBuyerAndSeller(notaryNode: StartedNode<MockNetwork.MockNode>,
private fun runBuyerAndSeller(notary: Party,
sellerNode: StartedNode<MockNetwork.MockNode>,
buyerNode: StartedNode<MockNetwork.MockNode>,
assetToSell: StateAndRef<OwnableState>,
anonymous: Boolean = true): RunResult {
val buyerFlows: Observable<out FlowLogic<*>> = buyerNode.internals.registerInitiatedFlow(BuyerAcceptor::class.java)
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
return RunResult(firstBuyerFiber, sellerResult, seller.stateMachine.id)
}
@InitiatingFlow
class SellerInitiator(private val buyer: Party,
private val notary: NodeInfo,
private val notary: Party,
private val assetToSell: StateAndRef<OwnableState>,
private val price: Amount<Currency>,
private val anonymous: Boolean) : FlowLogic<SignedTransaction>() {
@ -558,10 +562,9 @@ class TwoPartyTradeFlowTests {
} else {
ourIdentityAndCert
}
send(buyer, TestTx(notary.notaryIdentity, price, anonymous))
send(buyer, TestTx(notary, price, anonymous))
return subFlow(Seller(
buyer,
notary,
assetToSell,
price,
myPartyAndCert))
@ -596,17 +599,18 @@ class TwoPartyTradeFlowTests {
mockNet.runNetwork()
notaryNode.internals.ensureRegistered()
val notary = aliceNode.services.getDefaultNotary()
// Let the nodes know about each other - normally the network map would handle this
mockNet.registerIdentities()
val bobsBadCash = bobNode.database.transaction {
fillUpForBuyer(bobError, issuer, bobNode.info.chooseIdentity(),
notaryNode.info.notaryIdentity).second
notary).second
}
val alicesFakePaper = aliceNode.database.transaction {
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)
@ -614,7 +618,7 @@ class TwoPartyTradeFlowTests {
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()

View File

@ -6,7 +6,6 @@ import net.corda.core.flows.NotaryChangeFlow
import net.corda.core.flows.StateReplacementException
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.node.services.ServiceInfo
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.transactions.WireTransaction
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.services.network.NetworkMapService
import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.ServiceInfo
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.chooseIdentity
@ -36,6 +36,8 @@ class NotaryChangeTests {
lateinit var newNotaryNode: StartedNode<MockNetwork.MockNode>
lateinit var clientNodeA: StartedNode<MockNetwork.MockNode>
lateinit var clientNodeB: StartedNode<MockNetwork.MockNode>
lateinit var notaryNewId: Party
lateinit var notaryOldId: Party
@Before
fun setUp() {
@ -49,6 +51,8 @@ class NotaryChangeTests {
mockNet.registerIdentities()
mockNet.runNetwork() // Clear network map registration messages
oldNotaryNode.internals.ensureRegistered()
notaryNewId = newNotaryNode.info.legalIdentities[1]
notaryOldId = oldNotaryNode.info.legalIdentities[1]
}
@After
@ -58,8 +62,8 @@ class NotaryChangeTests {
@Test
fun `should change notary for a state with single participant`() {
val state = issueState(clientNodeA, oldNotaryNode)
val newNotary = newNotaryNode.info.notaryIdentity
val state = issueState(clientNodeA, oldNotaryNode, notaryOldId)
val newNotary = notaryNewId
val flow = NotaryChangeFlow(state, newNotary)
val future = clientNodeA.services.startFlow(flow)
@ -71,8 +75,8 @@ class NotaryChangeTests {
@Test
fun `should change notary for a state with multiple participants`() {
val state = issueMultiPartyState(clientNodeA, clientNodeB, oldNotaryNode)
val newNotary = newNotaryNode.info.notaryIdentity
val state = issueMultiPartyState(clientNodeA, clientNodeB, oldNotaryNode, notaryOldId)
val newNotary = notaryNewId
val flow = NotaryChangeFlow(state, newNotary)
val future = clientNodeA.services.startFlow(flow)
@ -87,7 +91,7 @@ class NotaryChangeTests {
@Test
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 flow = NotaryChangeFlow(state, newEvilNotary.party)
val future = clientNodeA.services.startFlow(flow)
@ -101,10 +105,10 @@ class NotaryChangeTests {
@Test
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 newNotary = newNotaryNode.info.notaryIdentity
val newNotary = notaryNewId
val flow = NotaryChangeFlow(state, newNotary)
val future = clientNodeA.services.startFlow(flow)
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 notary = notaryNode.info.notaryIdentity
val stateA = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
val stateB = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
val stateC = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
val tx = TransactionBuilder(null).apply {
addCommand(Command(DummyContract.Commands.Create(), owner.party.owningKey))
addOutputState(stateA, DUMMY_PROGRAM_ID, notary, encumbrance = 2) // Encumbered by stateB
addOutputState(stateC, DUMMY_PROGRAM_ID, notary)
addOutputState(stateB, DUMMY_PROGRAM_ID, notary, encumbrance = 1) // Encumbered by stateC
addOutputState(stateA, DUMMY_PROGRAM_ID, notaryIdentity, encumbrance = 2) // Encumbered by stateB
addOutputState(stateC, DUMMY_PROGRAM_ID, notaryIdentity)
addOutputState(stateB, DUMMY_PROGRAM_ID, notaryIdentity, encumbrance = 1) // Encumbered by stateC
}
val stx = node.services.signInitialTransaction(tx)
node.services.recordTransactions(stx)
@ -161,21 +163,21 @@ class NotaryChangeTests {
// - The transaction type is not a notary change transaction at all.
}
fun issueState(node: StartedNode<*>, notaryNode: StartedNode<*>): StateAndRef<*> {
val tx = DummyContract.generateInitial(Random().nextInt(), notaryNode.info.notaryIdentity, node.info.chooseIdentity().ref(0))
fun issueState(node: StartedNode<*>, notaryNode: StartedNode<*>, notaryIdentity: Party): StateAndRef<*> {
val tx = DummyContract.generateInitial(Random().nextInt(), notaryIdentity, node.info.chooseIdentity().ref(0))
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)
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,
listOf(nodeA.info.chooseIdentity(), nodeB.info.chooseIdentity())), DUMMY_PROGRAM_ID, notaryNode.info.notaryIdentity)
val tx = TransactionBuilder(notary = notaryNode.info.notaryIdentity).withItems(state, dummyCommand())
listOf(nodeA.info.chooseIdentity(), nodeB.info.chooseIdentity())), DUMMY_PROGRAM_ID, notaryIdentity)
val tx = TransactionBuilder(notary = notaryIdentity).withItems(state, dummyCommand())
val signedByA = nodeA.services.signInitialTransaction(tx)
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)
nodeB.services.recordTransactions(stx)
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.identity.AbstractParty
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.queryBy
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.utilities.getOrThrow
import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.statemachine.StateMachineManager
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.messaging.SingleMessageRecipient
import net.corda.core.node.NodeInfo
import net.corda.core.node.services.ServiceInfo
import net.corda.core.serialization.deserialize
import net.corda.core.utilities.getOrThrow
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.messaging.MessagingService
import net.corda.node.services.messaging.send

View File

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

View File

@ -60,8 +60,7 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() {
@Test
fun `restart node with DB map cache and no network map`() {
val alice = startNodesWithPort(listOf(ALICE), noNetworkMap = true)[0]
val partyNodes = alice.services.networkMapCache.partyNodes
assertTrue(NetworkMapService.type !in alice.info.advertisedServices.map { it.info.type })
val partyNodes = alice.services.networkMapCache.allNodes
assertEquals(NullNetworkMapService, alice.inNodeNetworkMapService)
assertEquals(infos.size, partyNodes.size)
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 nodes = startNodesWithPort(parties, noNetworkMap = true)
assertTrue(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService })
assertTrue(nodes.all { NetworkMapService.type !in it.info.advertisedServices.map { it.info.type } })
nodes.forEach {
val partyNodes = it.services.networkMapCache.partyNodes
val partyNodes = it.services.networkMapCache.allNodes
assertEquals(infos.size, partyNodes.size)
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 nodes = startNodesWithPort(parties, noNetworkMap = false)
assertTrue(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService })
assertTrue(nodes.all { NetworkMapService.type !in it.info.advertisedServices.map { it.info.type } })
nodes.forEach {
val partyNodes = it.services.networkMapCache.partyNodes
val partyNodes = it.services.networkMapCache.allNodes
assertEquals(infos.size, partyNodes.size)
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.
val charlie = startNodesWithPort(listOf(CHARLIE), noNetworkMap = false)[0]
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.
val nms = startNodesWithPort(listOf(DUMMY_NOTARY), noNetworkMap = false)[0]
@ -126,13 +123,13 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() {
assertTrue(nms.inNodeNetworkMapService != NullNetworkMapService)
assertTrue(infos.any { it.legalIdentities.toSet() == nms.info.legalIdentities.toSet() })
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.
checkConnectivity(listOf(otherNodes[0], nms)) // Checks connectivity from A to NMS.
val cacheA = otherNodes[0].services.networkMapCache.partyNodes
val cacheB = otherNodes[1].services.networkMapCache.partyNodes
val cacheC = charlie.services.networkMapCache.partyNodes
val cacheA = otherNodes[0].services.networkMapCache.allNodes
val cacheB = otherNodes[1].services.networkMapCache.allNodes
val cacheC = charlie.services.networkMapCache.allNodes
assertEquals(4, cacheC.size) // Charlie fetched data from NetworkMap
assertThat(cacheB).contains(charlie.info)
assertEquals(cacheA.toSet(), cacheB.toSet())

View File

@ -1,7 +1,7 @@
package net.corda.node.services.network
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.config.NodeConfiguration
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.messaging.MessageRecipients
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.serialization.deserialize
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.node.internal.InitiatedFlowFactory
import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.persistence.checkpoints
import net.corda.node.services.transactions.ValidatingNotaryService
@ -72,6 +72,8 @@ class FlowFrameworkTests {
private lateinit var node2: StartedNode<MockNode>
private lateinit var notary1: StartedNode<MockNode>
private lateinit var notary2: StartedNode<MockNode>
private lateinit var notary1Identity: Party
private lateinit var notary2Identity: Party
@Before
fun start() {
@ -95,6 +97,8 @@ class FlowFrameworkTests {
// We don't create a network map, so manually handle registrations
mockNet.registerIdentities()
notary1Identity = notary1.services.myInfo.legalIdentities[1]
notary2Identity = notary2.services.myInfo.legalIdentities[1]
}
@After
@ -333,11 +337,12 @@ class FlowFrameworkTests {
@Test
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(
2000.DOLLARS,
OpaqueBytes.of(0x01),
notary1.info.notaryIdentity)).resultFuture.getOrThrow()
notary1Identity)).resultFuture.getOrThrow()
// We pay a couple of times, the notary picking should go round robin
for (i in 1..3) {
val flow = node1.services.startFlow(CashPaymentFlow(500.DOLLARS, node2.info.chooseIdentity()))
@ -345,11 +350,11 @@ class FlowFrameworkTests {
flow.resultFuture.getOrThrow()
}
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)
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)
assertEquals(notary1Address, endpoint.getAddressOfParty(notary2.services.networkMapCache.getPartyInfo(notary2.info.notaryIdentity)!!))
assertEquals(notary1Address, endpoint.getAddressOfParty(notary2.services.networkMapCache.getPartyInfo(notary2Identity)!!))
receivedSessionMessages.expectEvents(isStrict = false) {
sequence(
// First Pay
@ -598,7 +603,7 @@ class FlowFrameworkTests {
@Test
fun `wait for transaction`() {
val ptx = TransactionBuilder(notary = notary1.info.notaryIdentity)
val ptx = TransactionBuilder(notary = notary1Identity)
.addOutputState(DummyState(), DUMMY_PROGRAM_ID)
.addCommand(dummyCommand(node1.info.chooseIdentity().owningKey))
val stx = node1.services.signInitialTransaction(ptx)
@ -613,7 +618,7 @@ class FlowFrameworkTests {
@Test
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)
.addCommand(dummyCommand())
val stx = node1.services.signInitialTransaction(ptx)
@ -630,7 +635,7 @@ class FlowFrameworkTests {
@Test
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)
.addCommand(dummyCommand(node1.info.chooseIdentity().owningKey))
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.NotaryException
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.TransactionBuilder
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.seconds
import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.network.NetworkMapService
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.chooseIdentity
import net.corda.testing.contracts.DummyContract
import net.corda.testing.dummyCommand
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
@ -32,6 +34,7 @@ class NotaryServiceTests {
lateinit var mockNet: MockNetwork
lateinit var notaryNode: StartedNode<MockNetwork.MockNode>
lateinit var clientNode: StartedNode<MockNetwork.MockNode>
lateinit var notary: Party
@Before
fun setup() {
@ -42,6 +45,7 @@ class NotaryServiceTests {
clientNode = mockNet.createNode(notaryNode.network.myAddress)
mockNet.runNetwork() // Clear network map registration messages
notaryNode.internals.ensureRegistered()
notary = clientNode.services.getDefaultNotary()
}
@After
@ -53,7 +57,7 @@ class NotaryServiceTests {
fun `should sign a unique transaction with a valid time-window`() {
val stx = run {
val inputState = issueState(clientNode)
val tx = TransactionBuilder(notaryNode.info.notaryIdentity)
val tx = TransactionBuilder(notary)
.addInputState(inputState)
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
.setTimeWindow(Instant.now(), 30.seconds)
@ -69,7 +73,7 @@ class NotaryServiceTests {
fun `should sign a unique transaction without a time-window`() {
val stx = run {
val inputState = issueState(clientNode)
val tx = TransactionBuilder(notaryNode.info.notaryIdentity)
val tx = TransactionBuilder(notary)
.addInputState(inputState)
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
clientNode.services.signInitialTransaction(tx)
@ -84,7 +88,7 @@ class NotaryServiceTests {
fun `should report error for transaction with an invalid time-window`() {
val stx = run {
val inputState = issueState(clientNode)
val tx = TransactionBuilder(notaryNode.info.notaryIdentity)
val tx = TransactionBuilder(notary)
.addInputState(inputState)
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
.setTimeWindow(Instant.now().plusSeconds(3600), 30.seconds)
@ -101,7 +105,7 @@ class NotaryServiceTests {
fun `should sign identical transaction multiple times (signing is idempotent)`() {
val stx = run {
val inputState = issueState(clientNode)
val tx = TransactionBuilder(notaryNode.info.notaryIdentity)
val tx = TransactionBuilder(notary)
.addInputState(inputState)
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
clientNode.services.signInitialTransaction(tx)
@ -121,13 +125,13 @@ class NotaryServiceTests {
fun `should report conflict when inputs are reused across transactions`() {
val inputState = issueState(clientNode)
val stx = run {
val tx = TransactionBuilder(notaryNode.info.notaryIdentity)
val tx = TransactionBuilder(notary)
.addInputState(inputState)
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
clientNode.services.signInitialTransaction(tx)
}
val stx2 = run {
val tx = TransactionBuilder(notaryNode.info.notaryIdentity)
val tx = TransactionBuilder(notary)
.addInputState(inputState)
.addInputState(issueState(clientNode))
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
@ -155,7 +159,7 @@ class NotaryServiceTests {
}
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 stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey)
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.NotaryException
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.utilities.getOrThrow
import net.corda.core.transactions.TransactionBuilder
import net.corda.node.internal.StartedNode
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.issueInvalidState
import net.corda.node.services.network.NetworkMapService
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.contracts.DummyContract
import net.corda.testing.dummyCommand
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
@ -33,6 +35,7 @@ class ValidatingNotaryServiceTests {
lateinit var mockNet: MockNetwork
lateinit var notaryNode: StartedNode<MockNetwork.MockNode>
lateinit var clientNode: StartedNode<MockNetwork.MockNode>
lateinit var notary: Party
@Before
fun setup() {
@ -44,6 +47,7 @@ class ValidatingNotaryServiceTests {
clientNode = mockNet.createNode(notaryNode.network.myAddress)
mockNet.runNetwork() // Clear network map registration messages
notaryNode.internals.ensureRegistered()
notary = clientNode.services.getDefaultNotary()
}
@After
@ -54,8 +58,8 @@ class ValidatingNotaryServiceTests {
@Test
fun `should report error for invalid transaction dependency`() {
val stx = run {
val inputState = issueInvalidState(clientNode, notaryNode.info.notaryIdentity)
val tx = TransactionBuilder(notaryNode.info.notaryIdentity)
val inputState = issueInvalidState(clientNode, notary)
val tx = TransactionBuilder(notary)
.addInputState(inputState)
.addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey))
clientNode.services.signInitialTransaction(tx)
@ -75,7 +79,7 @@ class ValidatingNotaryServiceTests {
val inputState = issueState(clientNode)
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)
}
@ -98,7 +102,7 @@ class ValidatingNotaryServiceTests {
}
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 stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey)
node.services.recordTransactions(stx)

View File

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

View File

@ -1,7 +1,7 @@
package net.corda.attachmentdemo
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_B
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.BankOfCordaWebApi.IssueRequestParams
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.testing.BOC
import net.corda.testing.driver.driver

View File

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

View File

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

View File

@ -36,20 +36,19 @@ class BankOfCordaClientApi(val hostAndPort: NetworkHostAndPort) {
// TODO: privileged security controls required
client.start("bankUser", "test").use { connection ->
val rpc = connection.proxy
rpc.waitUntilNetworkReady()
// Resolve parties via RPC
val issueToParty = rpc.partyFromX500Name(params.issueToPartyName)
?: throw Exception("Unable to locate ${params.issueToPartyName} in Network Map Service")
val notaryLegalIdentity = rpc.partyFromX500Name(params.notaryName)
?: 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 anonymous = true
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
}
}

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()
val notaryParty = rpc.partyFromX500Name(params.notaryName)
?: 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 anonymous = true
@ -56,7 +54,7 @@ class BankOfCordaWebApi(val rpc: CordaRPCOps) {
// invoke client side of Issuer Flow: IssuanceRequester
// The line below blocks and waits for the future to resolve.
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")
Response.status(Response.Status.CREATED).build()
} 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.identity.Party
import net.corda.core.messaging.vaultTrackBy
import net.corda.core.node.services.ServiceInfo
import net.corda.core.toFuture
import net.corda.core.utilities.NetworkHostAndPort
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.irs.contract.InterestRateSwap
import net.corda.irs.utilities.uploadFile
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.config.FullNodeConfiguration
import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User

View File

@ -47,8 +47,8 @@ object AutoOfferFlow {
@Suspendable
override fun call(): SignedTransaction {
require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" }
val notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity
require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" }
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
val otherParty = notUs(dealToBeOffered.participants).map { serviceHub.identityService.partyFromAnonymous(it) }.requireNoNulls().single()
progressTracker.currentStep = DEALING

View File

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

View File

@ -1,7 +1,7 @@
package net.corda.irs
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.testing.DUMMY_BANK_A
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.
*/
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 partyNodes = (serviceHub.networkMapCache.partyNodes.map { it.legalIdentitiesAndCerts.first().party } - notaryNodes).sortedBy { it.name.toString() }
return notaryNodes + partyNodes
val notaryParties = serviceHub.networkMapCache.notaryIdentities.map { it.party }
val peerParties = serviceHub.networkMapCache.allNodes.filter {
it.legalIdentities.all { !serviceHub.networkMapCache.isNotary(it) }
}.map { it.legalIdentities[0] }.sortedBy { it.name.toString() }
return notaryParties + peerParties
}
@Suspendable

View File

@ -138,6 +138,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten
node1.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java)
node2.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java)
val notaryId = node1.rpcOps.notaryIdentities().first().party
@InitiatingFlow
class StartDealFlow(val otherParty: Party,
val payload: AutoOffer) : FlowLogic<SignedTransaction>() {
@ -160,7 +161,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten
val instigator = StartDealFlow(
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
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.core.internal.uncheckedCast
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.irs.api.NodeInterestRates
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.network.NetworkMapService
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.stream
import net.corda.core.internal.toTypedArray
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.BFTNonValidatingNotaryService
import net.corda.node.services.transactions.minCorrectReplicas
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. */
private class NotaryDemoClientApi(val rpc: CordaRPCOps) {
private val notary by lazy {
val parties = rpc.networkMapSnapshot()
val id = parties.stream().filter { it.advertisedServices.any { it.info.type.isNotary() } }.map { it.notaryIdentity }.distinct().asSequence().singleOrNull()
val id = rpc.notaryIdentities().distinct().singleOrNull()?.party
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.core.identity.CordaX500Name
import net.corda.core.internal.div
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.RaftValidatingNotaryService
import net.corda.node.utilities.ServiceIdentityGenerator
import net.corda.testing.ALICE

View File

@ -1,7 +1,6 @@
package net.corda.notarydemo
import net.corda.core.internal.div
import net.corda.core.node.services.ServiceInfo
import net.corda.testing.ALICE
import net.corda.testing.BOB
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.cordform.CordformDefinition
import net.corda.cordform.CordformContext
import net.corda.nodeapi.ServiceInfo
import net.corda.testing.internal.demorun.*
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 net.corda.core.identity.CordaX500Name
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.testing.DUMMY_BANK_A
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.startFlow
import net.corda.core.messaging.vaultQueryBy
import net.corda.core.node.services.ServiceType
import net.corda.core.utilities.getOrThrow
import net.corda.finance.contracts.DealState
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.toPortfolio
import net.corda.vega.portfolio.toStateAndRef
import org.bouncycastle.asn1.x500.X500Name
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.ZoneId
@ -254,11 +252,11 @@ class PortfolioApi(val rpc: CordaRPCOps) {
@Produces(MediaType.APPLICATION_JSON)
fun getWhoAmI(): AvailableParties {
val parties = rpc.networkMapSnapshot()
val counterParties = parties.filterNot {
it.advertisedServices.any { it.info.type in setOf(ServiceType.networkMap, ServiceType.notary) }
|| ownParty in it.legalIdentitiesAndCerts.map { it.party }
val notaries = rpc.notaryIdentities()
// TODO We are not able to filter by network map node now
val counterParties = parties.filterNot { it.legalIdentitiesAndCerts.any { it in notaries }
|| ownParty in it.legalIdentities
}
return AvailableParties(
self = ApiParty(ownParty.owningKey.toBase58String(), ownParty.name),
// 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>() {
@Suspendable
override fun call(): SignedTransaction {
require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" }
val notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity
require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" }
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) =
if (swap.buyer.second == ourIdentity.owningKey) {
Pair(ourIdentity, otherParty)
@ -52,7 +52,7 @@ object IRSTradeFlow {
val offer = receive<OfferMessage>(replyToParty).unwrap { it }
// 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)
subFlow(TwoPartyDealFlow.Acceptor(replyToParty))
}

View File

@ -61,8 +61,8 @@ object SimmFlow {
@Suspendable
override fun call(): RevisionedState<PortfolioState.Update> {
logger.debug("Calling from: $ourIdentity. Sending to: $otherParty")
require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" }
notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity
require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" }
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 trades = serviceHub.vaultQueryService.queryBy<IRSState>(criteria).states

View File

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

View File

@ -1,7 +1,6 @@
package net.corda.traderdemo
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.millis
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.CommercialPaperSchemaV1
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User
import net.corda.testing.BOC

View File

@ -46,12 +46,10 @@ class TraderDemoClientApi(val rpc: CordaRPCOps) {
val ref = OpaqueBytes.of(1)
val buyer = rpc.partyFromX500Name(buyerName) ?: throw IllegalStateException("Don't know $buyerName")
val seller = rpc.partyFromX500Name(sellerName) ?: throw IllegalStateException("Don't know $sellerName")
val notaryLegalIdentity = rpc.partyFromX500Name(DUMMY_NOTARY.name)
?: 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 notaryIdentity = rpc.notaryIdentities().first().party
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
amounts.forEach { pennies ->
// 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.
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")
}

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)
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(
otherParty,
notary.notaryIdentity,
notary,
amount,
CommercialPaper.State::class.java)

View File

@ -40,7 +40,7 @@ class SellerFlow(private val otherParty: Party,
override fun call(): SignedTransaction {
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 commercialPaper = serviceHub.vaultQueryService.queryBy(CommercialPaper.State::class.java).states.first()
@ -50,7 +50,6 @@ class SellerFlow(private val otherParty: Party,
send(otherParty, amount)
val seller = TwoPartyTradeFlow.Seller(
otherParty,
notary,
commercialPaper,
amount,
cpOwner,

View File

@ -1,9 +1,9 @@
package net.corda.traderdemo
import net.corda.core.internal.div
import net.corda.core.node.services.ServiceInfo
import net.corda.finance.flows.CashIssueFlow
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.ServiceInfo
import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User
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.internal.div
import net.corda.core.internal.list
import net.corda.core.node.services.ServiceInfo
import net.corda.core.internal.readLines
import net.corda.core.utilities.getOrThrow
import net.corda.testing.DUMMY_BANK_A
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.DUMMY_REGULATOR
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.testing.ProjectStructure.projectRootDir
import org.assertj.core.api.Assertions.assertThat
@ -42,7 +41,7 @@ class DriverTests {
fun `simple node startup and shutdown`() {
val handles = driver {
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))
}
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.MockStateMachineRecordedTransactionMappingStorage
import net.corda.testing.node.MockTransactionStorage
import java.security.PublicKey
import java.sql.Connection
import java.time.Clock
@ -67,6 +68,8 @@ open class MockServiceHubInternal(
get() = overrideClock ?: throw UnsupportedOperationException()
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.
override val notaryIdentityKey: PublicKey
get() = throw IllegalStateException("No notary identity in MockServiceHubInternal")
override val monitoringService: MonitoringService = MonitoringService(MetricRegistry())
override val rpcFlows: List<Class<out FlowLogic<*>>>
get() = throw UnsupportedOperationException()

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