Clean up API for selecting notaries (#1573)

* Remove getAnyNotary() from network map API.
Change notaryIdentities() signature to return a Party instead of PartyAndCertificate.
Some API doc updates.

* Minor API doc formatting and typo fix

* Update changelog

* Address comments

* Address comments
This commit is contained in:
Andrius Dagys 2017-09-21 10:28:18 +01:00 committed by josecoll
parent fd9c79659d
commit 0314e650a4
39 changed files with 118 additions and 144 deletions

View File

@ -8,6 +8,7 @@ import javafx.collections.ObservableList
import net.corda.client.jfx.utils.fold import net.corda.client.jfx.utils.fold
import net.corda.client.jfx.utils.map import net.corda.client.jfx.utils.map
import net.corda.core.identity.AnonymousParty import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.services.NetworkMapCache.MapChange import net.corda.core.node.services.NetworkMapCache.MapChange
@ -36,9 +37,9 @@ class NetworkIdentityModel {
publicKey?.let { rpcProxy.map { it?.nodeInfoFromParty(AnonymousParty(publicKey)) } } publicKey?.let { rpcProxy.map { it?.nodeInfoFromParty(AnonymousParty(publicKey)) } }
}) })
val notaries: ObservableList<PartyAndCertificate> = FXCollections.observableList(rpcProxy.value?.notaryIdentities()) val notaries: ObservableList<Party> = FXCollections.observableList(rpcProxy.value?.notaryIdentities())
val notaryNodes: ObservableList<NodeInfo> = FXCollections.observableList(notaries.map { rpcProxy.value?.nodeInfoFromParty(it.party) }) val notaryNodes: ObservableList<NodeInfo> = FXCollections.observableList(notaries.map { rpcProxy.value?.nodeInfoFromParty(it) })
val parties: ObservableList<NodeInfo> = networkIdentities.filtered { it.legalIdentitiesAndCerts.all { it !in notaries } } val parties: ObservableList<NodeInfo> = networkIdentities.filtered { it.legalIdentities.all { it !in notaries } }
val myIdentity = rpcProxy.map { it?.nodeInfo()?.legalIdentitiesAndCerts?.first()?.party } val myIdentity = rpcProxy.map { it?.nodeInfo()?.legalIdentitiesAndCerts?.first()?.party }
fun partyFromPublicKey(publicKey: PublicKey): ObservableValue<NodeInfo?> = identityCache[publicKey] fun partyFromPublicKey(publicKey: PublicKey): ObservableValue<NodeInfo?> = identityCache[publicKey]

View File

@ -5,7 +5,7 @@ import net.corda.client.rpc.CordaRPCClient
import net.corda.client.rpc.CordaRPCClientConfiguration import net.corda.client.rpc.CordaRPCClientConfiguration
import net.corda.core.contracts.ContractState import net.corda.core.contracts.ContractState
import net.corda.core.flows.StateMachineRunId import net.corda.core.flows.StateMachineRunId
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.Party
import net.corda.core.messaging.* import net.corda.core.messaging.*
import net.corda.core.node.services.NetworkMapCache.MapChange import net.corda.core.node.services.NetworkMapCache.MapChange
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
@ -46,7 +46,7 @@ class NodeMonitorModel {
val networkMap: Observable<MapChange> = networkMapSubject val networkMap: Observable<MapChange> = networkMapSubject
val proxyObservable = SimpleObjectProperty<CordaRPCOps?>() val proxyObservable = SimpleObjectProperty<CordaRPCOps?>()
lateinit var notaryIdentities: List<PartyAndCertificate> lateinit var notaryIdentities: List<Party>
/** /**
* Register for updates to/from a given vault. * Register for updates to/from a given vault.

View File

@ -9,7 +9,6 @@ import net.corda.core.flows.StateMachineRunId
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.NetworkMapCache
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
@ -59,13 +58,12 @@ interface CordaRPCOps : RPCOps {
*/ */
override val protocolVersion: Int get() = nodeInfo().platformVersion override val protocolVersion: Int get() = nodeInfo().platformVersion
/** /** Returns a list of currently in-progress state machine infos. */
* Returns a list of currently in-progress state machine infos.
*/
fun stateMachinesSnapshot(): List<StateMachineInfo> fun stateMachinesSnapshot(): List<StateMachineInfo>
/** /**
* Returns a data feed of currently in-progress state machine infos and an observable of future state machine adds/removes. * Returns a data feed of currently in-progress state machine infos and an observable of
* future state machine adds/removes.
*/ */
@RPCReturnsObservables @RPCReturnsObservables
fun stateMachinesFeed(): DataFeed<List<StateMachineInfo>, StateMachineUpdate> fun stateMachinesFeed(): DataFeed<List<StateMachineInfo>, StateMachineUpdate>
@ -172,9 +170,7 @@ interface CordaRPCOps : RPCOps {
@RPCReturnsObservables @RPCReturnsObservables
fun internalVerifiedTransactionsFeed(): DataFeed<List<SignedTransaction>, SignedTransaction> fun internalVerifiedTransactionsFeed(): DataFeed<List<SignedTransaction>, SignedTransaction>
/** /** Returns a snapshot list of existing state machine id - recorded transaction hash mappings. */
* Returns a snapshot list of existing state machine id - recorded transaction hash mappings.
*/
fun stateMachineRecordedTransactionMappingSnapshot(): List<StateMachineTransactionMapping> fun stateMachineRecordedTransactionMappingSnapshot(): List<StateMachineTransactionMapping>
/** /**
@ -184,19 +180,19 @@ interface CordaRPCOps : RPCOps {
@RPCReturnsObservables @RPCReturnsObservables
fun stateMachineRecordedTransactionMappingFeed(): DataFeed<List<StateMachineTransactionMapping>, StateMachineTransactionMapping> fun stateMachineRecordedTransactionMappingFeed(): DataFeed<List<StateMachineTransactionMapping>, StateMachineTransactionMapping>
/** /** Returns all parties currently visible on the network with their advertised services. */
* Returns all parties currently visible on the network with their advertised services.
*/
fun networkMapSnapshot(): List<NodeInfo> fun networkMapSnapshot(): List<NodeInfo>
/** /**
* Returns all parties currently visible on the network with their advertised services and an observable of future updates to the network. * Returns all parties currently visible on the network with their advertised services and an observable of
* future updates to the network.
*/ */
@RPCReturnsObservables @RPCReturnsObservables
fun networkMapFeed(): DataFeed<List<NodeInfo>, NetworkMapCache.MapChange> fun networkMapFeed(): DataFeed<List<NodeInfo>, NetworkMapCache.MapChange>
/** /**
* Start the given flow with the given arguments. [logicType] must be annotated with [net.corda.core.flows.StartableByRPC]. * Start the given flow with the given arguments. [logicType] must be annotated
* with [net.corda.core.flows.StartableByRPC].
*/ */
@RPCReturnsObservables @RPCReturnsObservables
fun <T> startFlowDynamic(logicType: Class<out FlowLogic<T>>, vararg args: Any?): FlowHandle<T> fun <T> startFlowDynamic(logicType: Class<out FlowLogic<T>>, vararg args: Any?): FlowHandle<T>
@ -208,44 +204,32 @@ interface CordaRPCOps : RPCOps {
@RPCReturnsObservables @RPCReturnsObservables
fun <T> startTrackedFlowDynamic(logicType: Class<out FlowLogic<T>>, vararg args: Any?): FlowProgressHandle<T> fun <T> startTrackedFlowDynamic(logicType: Class<out FlowLogic<T>>, vararg args: Any?): FlowProgressHandle<T>
/** /** Returns Node's NodeInfo, assuming this will not change while the node is running. */
* Returns Node's NodeInfo, assuming this will not change while the node is running.
*/
fun nodeInfo(): NodeInfo fun nodeInfo(): NodeInfo
/** /**
* Returns network's notary identities, assuming this will not change while the node is running. * Returns network's notary identities, assuming this will not change while the node is running.
*
* Note that the identities are sorted based on legal name, and the ordering might change once new notaries are introduced.
*/ */
fun notaryIdentities(): List<PartyAndCertificate> fun notaryIdentities(): List<Party>
/* /** Add note(s) to an existing Vault transaction. */
* Add note(s) to an existing Vault transaction
*/
fun addVaultTransactionNote(txnId: SecureHash, txnNote: String) fun addVaultTransactionNote(txnId: SecureHash, txnNote: String)
/* /** Retrieve existing note(s) for a given Vault transaction. */
* Retrieve existing note(s) for a given Vault transaction
*/
fun getVaultTransactionNotes(txnId: SecureHash): Iterable<String> fun getVaultTransactionNotes(txnId: SecureHash): Iterable<String>
/** /** Checks whether an attachment with the given hash is stored on the node. */
* Checks whether an attachment with the given hash is stored on the node.
*/
fun attachmentExists(id: SecureHash): Boolean fun attachmentExists(id: SecureHash): Boolean
/** /** Download an attachment JAR by ID. */
* Download an attachment JAR by ID
*/
fun openAttachment(id: SecureHash): InputStream fun openAttachment(id: SecureHash): InputStream
/** /** Uploads a jar to the node, returns it's hash. */
* Uploads a jar to the node, returns it's hash.
*/
fun uploadAttachment(jar: InputStream): SecureHash fun uploadAttachment(jar: InputStream): SecureHash
/** /** Returns the node's current time. */
* Returns the node's current time.
*/
fun currentNodeTime(): Instant fun currentNodeTime(): Instant
/** /**
@ -266,14 +250,10 @@ interface CordaRPCOps : RPCOps {
* @return well known identity, if found. * @return well known identity, if found.
*/ */
fun partyFromAnonymous(party: AbstractParty): Party? fun partyFromAnonymous(party: AbstractParty): Party?
/** /** Returns the [Party] corresponding to the given key, if found. */
* Returns the [Party] corresponding to the given key, if found.
*/
fun partyFromKey(key: PublicKey): Party? fun partyFromKey(key: PublicKey): Party?
/** /** Returns the [Party] with the X.500 principal as it's [Party.name]. */
* Returns the [Party] with the X.500 principal as it's [Party.name]
*/
fun partyFromX500Name(x500Name: CordaX500Name): Party? fun partyFromX500Name(x500Name: CordaX500Name): Party?
/** /**
@ -296,9 +276,7 @@ interface CordaRPCOps : RPCOps {
*/ */
fun nodeInfoFromParty(party: AbstractParty): NodeInfo? fun nodeInfoFromParty(party: AbstractParty): NodeInfo?
/** /** Clear all network map data from local node cache. */
* Clear all network map data from local node cache.
*/
fun clearNetworkMapCache() fun clearNetworkMapCache()
} }

View File

@ -7,7 +7,7 @@ import kotlin.annotation.AnnotationTarget.CLASS
/** /**
* Annotate any class that needs to be a long-lived service within the node, such as an oracle, with this annotation. * Annotate any class that needs to be a long-lived service within the node, such as an oracle, with this annotation.
* Such a class needs to have a constructor with a single parameter of type [ServiceHub]. This construtor will be invoked * Such a class needs to have a constructor with a single parameter of type [ServiceHub]. This constructor will be invoked
* during node start to initialise the service. The service hub provided can be used to get information about the node * during node start to initialise the service. The service hub provided can be used to get information about the node
* that may be necessary for the service. Corda services are created as singletons within the node and are available * that may be necessary for the service. Corda services are created as singletons within the node and are available
* to flows via [ServiceHub.cordaService]. * to flows via [ServiceHub.cordaService].

View File

@ -1,12 +1,9 @@
package net.corda.core.node.services package net.corda.core.node.services
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture
import net.corda.core.contracts.Contract
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.randomOrNull
import net.corda.core.messaging.DataFeed import net.corda.core.messaging.DataFeed
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
@ -31,10 +28,14 @@ interface NetworkMapCache {
data class Modified(override val node: NodeInfo, val previousNode: NodeInfo) : MapChange() data class Modified(override val node: NodeInfo, val previousNode: NodeInfo) : MapChange()
} }
/** A list of notary services available on the network */ /**
* A list of notary services available on the network.
*
* Note that the identities are sorted based on legal name, and the ordering might change once new notaries are introduced.
*/
// TODO this list will be taken from NetworkParameters distributed by NetworkMap. // TODO this list will be taken from NetworkParameters distributed by NetworkMap.
val notaryIdentities: List<PartyAndCertificate> val notaryIdentities: List<Party>
/** Tracks changes to the network map cache */ /** Tracks changes to the network map cache. */
val changed: Observable<MapChange> val changed: Observable<MapChange>
/** Future to track completion of the NetworkMapService registration. */ /** Future to track completion of the NetworkMapService registration. */
val nodeReady: CordaFuture<Void?> val nodeReady: CordaFuture<Void?>
@ -66,7 +67,7 @@ interface NetworkMapCache {
it.legalIdentitiesAndCerts.singleOrNull { it.name == name }?.party it.legalIdentitiesAndCerts.singleOrNull { it.name == name }?.party
} }
/** Return all [NodeInfo]s the node currently is aware of (including ourselves). */ /** Return all [NodeInfo]s the node currently is aware of (including ourselves). */
val allNodes: List<NodeInfo> val allNodes: List<NodeInfo>
/** /**
@ -81,25 +82,17 @@ interface NetworkMapCache {
fun getPartyInfo(party: Party): PartyInfo? fun getPartyInfo(party: Party): PartyInfo?
/** Gets a notary identity by the given name. */ /** Gets a notary identity by the given name. */
fun getNotary(name: CordaX500Name): Party? = notaryIdentities.firstOrNull { it.name == name }?.party fun getNotary(name: CordaX500Name): Party? = notaryIdentities.firstOrNull { it.name == name }
/** /** Checks whether a given party is an advertised notary identity. */
* Returns a notary identity advertised by any of the nodes on the network (chosen at random) fun isNotary(party: Party): Boolean = party in notaryIdentities
* @param type Limits the result to notaries of the specified type (optional)
*/
fun getAnyNotary(): Party? = notaryIdentities.randomOrNull()?.party
/** Checks whether a given party is an advertised notary identity */ /** Checks whether a given party is an validating notary identity. */
fun isNotary(party: Party): Boolean = notaryIdentities.any { party == it.party }
/** Checks whether a given party is an validating notary identity */
fun isValidatingNotary(party: Party): Boolean { fun isValidatingNotary(party: Party): Boolean {
val notary = notaryIdentities.firstOrNull { it.party == party } ?: require(isNotary(party)) { "No notary found with identity $party." }
throw IllegalArgumentException("No notary found with identity $party.") return !party.name.toString().contains("corda.notary.simple", true) // TODO This implementation will change after introducing of NetworkParameters.
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. /** Clear all network map data from local node cache. */
*/
fun clearNetworkMapCache() fun clearNetworkMapCache()
} }

View File

@ -18,7 +18,7 @@ UNRELEASED
* We no longer support advertising services in network map. Removed ``NodeInfo::advertisedServices``, ``serviceIdentities`` * We no longer support advertising services in network map. Removed ``NodeInfo::advertisedServices``, ``serviceIdentities``
and ``notaryIdentity``. and ``notaryIdentity``.
* Removed service methods from ``NetworkMapCache``: ``partyNodes``, ``networkMapNodes``, ``notaryNodes``, ``regulatorNodes``, * Removed service methods from ``NetworkMapCache``: ``partyNodes``, ``networkMapNodes``, ``notaryNodes``, ``regulatorNodes``,
``getNodesWithService``, ``getPeersWithService``, ``getRecommended``, ``getNodesByAdvertisedServiceIdentityKey``, ``getNodesWithService``, ``getPeersWithService``, ``getRecommended``, ``getNodesByAdvertisedServiceIdentityKey``, ``getAnyNotary``,
``notaryNode``, ``getAnyServiceOfType``. To get all known ``NodeInfo``s call ``allNodes``. ``notaryNode``, ``getAnyServiceOfType``. To get all known ``NodeInfo``s call ``allNodes``.
* In preparation for ``NetworkMapService`` redesign and distributing notaries through ``NetworkParameters`` we added * 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`` ``NetworkMapCache::notaryIdentities`` list to enable to lookup for notary parties known to the network. Related ``CordaRPCOps::notaryIdentities``

View File

@ -56,7 +56,7 @@ class IntegrationTestingTutorial {
// START 4 // START 4
val issueRef = OpaqueBytes.of(0) val issueRef = OpaqueBytes.of(0)
val notaryParty = aliceProxy.notaryIdentities().first().party val notaryParty = aliceProxy.notaryIdentities().first()
(1..10).map { i -> (1..10).map { i ->
aliceProxy.startFlow(::CashIssueFlow, aliceProxy.startFlow(::CashIssueFlow,
i.DOLLARS, i.DOLLARS,

View File

@ -125,11 +125,10 @@ public class FlowCookbookJava {
// We retrieve a notary from the network map. // We retrieve a notary from the network map.
// DOCSTART 1 // DOCSTART 1
Party specificNotary = getServiceHub().getNetworkMapCache().getNotary(new CordaX500Name("Notary Service", "London", "UK")); Party specificNotary = getServiceHub().getNetworkMapCache().getNotary(new CordaX500Name("Notary Service", "London", "UK"));
Party anyNotary = getServiceHub().getNetworkMapCache().getAnyNotary(); // Alternatively, we can pick an arbitrary notary from the notary list. However, it is always preferable to
// Unlike the first two methods, ``getNotaryNodes`` returns a // specify which notary to use explicitly, as the notary list might change when new notaries are introduced,
// ``List<NodeInfo>``. We have to extract the notary identity of // or old ones decommissioned.
// the node we want. Party firstNotary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
Party firstNotary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0).getParty();
// DOCEND 1 // DOCEND 1
// We may also need to identify a specific counterparty. // We may also need to identify a specific counterparty.

View File

@ -113,7 +113,7 @@ fun generateTransactions(proxy: CordaRPCOps) {
sum + state.state.data.amount.quantity sum + state.state.data.amount.quantity
} }
val issueRef = OpaqueBytes.of(0) val issueRef = OpaqueBytes.of(0)
val notary = proxy.notaryIdentities().first().party val notary = proxy.notaryIdentities().first()
val me = proxy.nodeInfo().legalIdentities.first() val me = proxy.nodeInfo().legalIdentities.first()
while (true) { while (true) {
Thread.sleep(1000) Thread.sleep(1000)

View File

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

View File

@ -104,11 +104,10 @@ object FlowCookbook {
// We retrieve the notary from the network map. // We retrieve the notary from the network map.
// DOCSTART 1 // DOCSTART 1
val specificNotary: Party? = serviceHub.networkMapCache.getNotary(CordaX500Name(organisation = "Notary Service", locality = "London", country = "UK")) val specificNotary: Party? = serviceHub.networkMapCache.getNotary(CordaX500Name(organisation = "Notary Service", locality = "London", country = "UK"))
val anyNotary: Party? = serviceHub.networkMapCache.getAnyNotary() // Alternatively, we can pick an arbitrary notary from the notary list. However, it is always preferable to
// Unlike the first two methods, ``getNotaryNodes`` returns a // specify which notary to use explicitly, as the notary list might change when new notaries are introduced,
// ``List<NodeInfo>``. We have to extract the notary identity of // or old ones decommissioned.
// the node we want. val firstNotary: Party = serviceHub.networkMapCache.notaryIdentities.first()
val firstNotary: Party = serviceHub.networkMapCache.notaryIdentities[0].party
// DOCEND 1 // DOCEND 1
// We may also need to identify a specific counterparty. We // We may also need to identify a specific counterparty. We

View File

@ -39,7 +39,7 @@ private fun gatherOurInputs(serviceHub: ServiceHub,
val ourParties = ourKeys.map { serviceHub.identityService.partyFromKey(it) ?: throw IllegalStateException("Unable to resolve party from key") } val ourParties = ourKeys.map { serviceHub.identityService.partyFromKey(it) ?: throw IllegalStateException("Unable to resolve party from key") }
val fungibleCriteria = QueryCriteria.FungibleAssetQueryCriteria(owner = ourParties) val fungibleCriteria = QueryCriteria.FungibleAssetQueryCriteria(owner = ourParties)
val notaries = notary ?: serviceHub.networkMapCache.getAnyNotary() val notaries = notary ?: serviceHub.networkMapCache.notaryIdentities.first()
val vaultCriteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(notary = listOf(notaries as AbstractParty)) val vaultCriteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(notary = listOf(notaries as AbstractParty))
val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.equal(amountRequired.token.product.currencyCode) } val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.equal(amountRequired.token.product.currencyCode) }

View File

@ -17,7 +17,6 @@ import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.seconds import net.corda.core.utilities.seconds
import net.corda.core.utilities.unwrap import net.corda.core.utilities.unwrap
import net.corda.testing.chooseIdentity
// Minimal state model of a manual approval process // Minimal state model of a manual approval process
@CordaSerializable @CordaSerializable
@ -102,7 +101,7 @@ class SubmitTradeApprovalFlow(private val tradeId: String,
// Manufacture an initial state // Manufacture an initial state
val tradeProposal = TradeApprovalContract.State(tradeId, ourIdentity, counterparty) val tradeProposal = TradeApprovalContract.State(tradeId, ourIdentity, counterparty)
// identify a notary. This might also be done external to the flow // identify a notary. This might also be done external to the flow
val notary = serviceHub.networkMapCache.getAnyNotary() val notary = serviceHub.networkMapCache.notaryIdentities.first()
// Create the TransactionBuilder and populate with the new state. // Create the TransactionBuilder and populate with the new state.
val tx = TransactionBuilder(notary).withItems( val tx = TransactionBuilder(notary).withItems(
StateAndContract(tradeProposal, TRADE_APPROVAL_PROGRAM_ID), StateAndContract(tradeProposal, TRADE_APPROVAL_PROGRAM_ID),

View File

@ -110,7 +110,7 @@ class NodePerformanceTests {
a as NodeHandle.InProcess a as NodeHandle.InProcess
val metricRegistry = startReporter(shutdownManager, a.node.services.monitoringService.metrics) val metricRegistry = startReporter(shutdownManager, a.node.services.monitoringService.metrics)
a.rpcClientToNode().use("A", "A") { connection -> a.rpcClientToNode().use("A", "A") { connection ->
val notary = connection.proxy.notaryIdentities().first().party val notary = connection.proxy.notaryIdentities().first()
println("ISSUING") println("ISSUING")
val doneFutures = (1..100).toList().parallelStream().map { val doneFutures = (1..100).toList().parallelStream().map {
connection.proxy.startFlow(::CashIssueFlow, 1.DOLLARS, OpaqueBytes.of(0), notary).returnValue connection.proxy.startFlow(::CashIssueFlow, 1.DOLLARS, OpaqueBytes.of(0), notary).returnValue

View File

@ -5,6 +5,7 @@ import net.corda.core.crypto.random63BitValue
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.concurrent.transpose import net.corda.core.internal.concurrent.transpose
import net.corda.core.internal.elapsedTime import net.corda.core.internal.elapsedTime
import net.corda.core.internal.randomOrNull
import net.corda.core.internal.times import net.corda.core.internal.times
import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.MessageRecipients
import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.messaging.SingleMessageRecipient
@ -55,7 +56,8 @@ class P2PMessagingTest : NodeBasedTest() {
networkMapNode.respondWith("Hello") networkMapNode.respondWith("Hello")
val alice = startNode(ALICE.name).getOrThrow() val alice = startNode(ALICE.name).getOrThrow()
val serviceAddress = alice.services.networkMapCache.run { val serviceAddress = alice.services.networkMapCache.run {
alice.network.getAddressOfParty(getPartyInfo(getAnyNotary()!!)!!) val notaryParty = notaryIdentities.randomOrNull()!!
alice.network.getAddressOfParty(getPartyInfo(notaryParty)!!)
} }
val received = alice.receiveFrom(serviceAddress).getOrThrow(10.seconds) val received = alice.receiveFrom(serviceAddress).getOrThrow(10.seconds)
assertThat(received).isEqualTo("Hello") assertThat(received).isEqualTo("Hello")
@ -100,7 +102,8 @@ class P2PMessagingTest : NodeBasedTest() {
val distributedServiceNodes = startNotaryCluster(DISTRIBUTED_SERVICE_NAME, 2).getOrThrow() val distributedServiceNodes = startNotaryCluster(DISTRIBUTED_SERVICE_NAME, 2).getOrThrow()
val alice = startNode(ALICE.name, configOverrides = mapOf("messageRedeliveryDelaySeconds" to 1)).getOrThrow() val alice = startNode(ALICE.name, configOverrides = mapOf("messageRedeliveryDelaySeconds" to 1)).getOrThrow()
val serviceAddress = alice.services.networkMapCache.run { val serviceAddress = alice.services.networkMapCache.run {
alice.network.getAddressOfParty(getPartyInfo(getAnyNotary()!!)!!) val notaryParty = notaryIdentities.randomOrNull()!!
alice.network.getAddressOfParty(getPartyInfo(notaryParty)!!)
} }
val dummyTopic = "dummy.topic" val dummyTopic = "dummy.topic"
@ -131,7 +134,8 @@ class P2PMessagingTest : NodeBasedTest() {
val distributedServiceNodes = startNotaryCluster(DISTRIBUTED_SERVICE_NAME, 2).getOrThrow() val distributedServiceNodes = startNotaryCluster(DISTRIBUTED_SERVICE_NAME, 2).getOrThrow()
val alice = startNode(ALICE.name, configOverrides = mapOf("messageRedeliveryDelaySeconds" to 1)).getOrThrow() val alice = startNode(ALICE.name, configOverrides = mapOf("messageRedeliveryDelaySeconds" to 1)).getOrThrow()
val serviceAddress = alice.services.networkMapCache.run { val serviceAddress = alice.services.networkMapCache.run {
alice.network.getAddressOfParty(getPartyInfo(getAnyNotary()!!)!!) val notaryParty = notaryIdentities.randomOrNull()!!
alice.network.getAddressOfParty(getPartyInfo(notaryParty)!!)
} }
val dummyTopic = "dummy.topic" val dummyTopic = "dummy.topic"

View File

@ -136,7 +136,7 @@ class SendMessageFlow(private val message: Message) : FlowLogic<SignedTransactio
@Suspendable @Suspendable
override fun call(): SignedTransaction { override fun call(): SignedTransaction {
val notary = serviceHub.networkMapCache.getAnyNotary() val notary = serviceHub.networkMapCache.notaryIdentities.first()
progressTracker.currentStep = GENERATING_TRANSACTION progressTracker.currentStep = GENERATING_TRANSACTION

View File

@ -10,7 +10,6 @@ import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.messaging.* import net.corda.core.messaging.*
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.NetworkMapCache
@ -115,7 +114,7 @@ class CordaRPCOpsImpl(
return services.myInfo return services.myInfo
} }
override fun notaryIdentities(): List<PartyAndCertificate> { override fun notaryIdentities(): List<Party> {
return services.networkMapCache.notaryIdentities return services.networkMapCache.notaryIdentities
} }

View File

@ -4,7 +4,6 @@ import net.corda.core.concurrent.CordaFuture
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.VisibleForTesting import net.corda.core.internal.VisibleForTesting
import net.corda.core.internal.bufferUntilSubscribed import net.corda.core.internal.bufferUntilSubscribed
import net.corda.core.internal.concurrent.map import net.corda.core.internal.concurrent.map
@ -73,11 +72,20 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
// 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. // 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. // This should eliminate the only required usage of services.
// It is ensured on node startup when constructing a notary that the name contains "notary". // It is ensured on node startup when constructing a notary that the name contains "notary".
override val notaryIdentities: List<PartyAndCertificate> get() { override val notaryIdentities: List<Party>
return partyNodes.flatMap { it.legalIdentitiesAndCerts }.filter { get() {
it.name.toString().contains("corda.notary", true) return partyNodes
}.distinct().sortedBy { it.name.toString() } // Distinct, because of distributed service nodes. .flatMap {
} // TODO: validate notary identity certificates before loading into network map cache.
// Notary certificates have to be signed by the doorman directly
it.legalIdentities
}
.filter {
it.name.toString().contains("corda.notary", true)
}
.distinct() // Distinct, because of distributed service nodes
.sortedBy { it.name.toString() }
}
init { init {
serviceHub.database.transaction { loadFromDB() } serviceHub.database.transaction { loadFromDB() }
@ -127,9 +135,9 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
data = NetworkMapService.UpdateAcknowledge(req.mapVersion, network.myAddress).serialize().bytes) data = NetworkMapService.UpdateAcknowledge(req.mapVersion, network.myAddress).serialize().bytes)
network.send(ackMessage, req.replyTo) network.send(ackMessage, req.replyTo)
processUpdatePush(req) processUpdatePush(req)
} catch(e: NodeMapError) { } catch (e: NodeMapError) {
logger.warn("Failure during node map update due to bad update: ${e.javaClass.name}") logger.warn("Failure during node map update due to bad update: ${e.javaClass.name}")
} catch(e: Exception) { } catch (e: Exception) {
logger.error("Exception processing update from network map service", e) logger.error("Exception processing update from network map service", e)
} }
} }
@ -183,7 +191,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
// Fetch the network map and register for updates at the same time // Fetch the network map and register for updates at the same time
val req = NetworkMapService.SubscribeRequest(false, network.myAddress) val req = NetworkMapService.SubscribeRequest(false, network.myAddress)
// `network.getAddressOfParty(partyInfo)` is a work-around for MockNetwork and InMemoryMessaging to get rid of SingleMessageRecipient in NodeInfo. // `network.getAddressOfParty(partyInfo)` is a work-around for MockNetwork and InMemoryMessaging to get rid of SingleMessageRecipient in NodeInfo.
val address = getPartyInfo(mapParty)?.let{ network.getAddressOfParty(it) } ?: val address = getPartyInfo(mapParty)?.let { network.getAddressOfParty(it) } ?:
throw IllegalArgumentException("Can't deregister for updates, don't know the party: $mapParty") throw IllegalArgumentException("Can't deregister for updates, don't know the party: $mapParty")
val future = network.sendRequest<SubscribeResponse>(NetworkMapService.SUBSCRIPTION_TOPIC, req, address).map { val future = network.sendRequest<SubscribeResponse>(NetworkMapService.SUBSCRIPTION_TOPIC, req, address).map {
if (it.confirmed) Unit else throw NetworkCacheError.DeregistrationFailed() if (it.confirmed) Unit else throw NetworkCacheError.DeregistrationFailed()
@ -201,11 +209,12 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
} }
} }
override val allNodes: List<NodeInfo> get () = serviceHub.database.transaction { override val allNodes: List<NodeInfo>
createSession { get () = serviceHub.database.transaction {
getAllInfos(it).map { it.toNodeInfo() } createSession {
getAllInfos(it).map { it.toNodeInfo() }
}
} }
}
private fun processRegistration(reg: NodeRegistration) { private fun processRegistration(reg: NodeRegistration) {
// TODO: Implement filtering by sequence number, so we only accept changes that are // TODO: Implement filtering by sequence number, so we only accept changes that are
@ -333,7 +342,8 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
addresses = nodeInfo.addresses.map { NodeInfoSchemaV1.DBHostAndPort.fromHostAndPort(it) }, addresses = nodeInfo.addresses.map { NodeInfoSchemaV1.DBHostAndPort.fromHostAndPort(it) },
// TODO Another ugly hack with special first identity... // TODO Another ugly hack with special first identity...
legalIdentitiesAndCerts = nodeInfo.legalIdentitiesAndCerts.mapIndexed { idx, elem -> legalIdentitiesAndCerts = nodeInfo.legalIdentitiesAndCerts.mapIndexed { idx, elem ->
NodeInfoSchemaV1.DBPartyAndCertificate(elem, isMain = idx == 0) }, NodeInfoSchemaV1.DBPartyAndCertificate(elem, isMain = idx == 0)
},
platformVersion = nodeInfo.platformVersion, platformVersion = nodeInfo.platformVersion,
serial = nodeInfo.serial serial = nodeInfo.serial
) )

View File

@ -80,7 +80,7 @@ class CordaRPCOpsImplTest {
mockNet.runNetwork() mockNet.runNetwork()
networkMap.internals.ensureRegistered() networkMap.internals.ensureRegistered()
notary = rpc.notaryIdentities().first().party notary = rpc.notaryIdentities().first()
} }
@After @After

View File

@ -24,6 +24,7 @@ import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.contracts.DUMMY_PROGRAM_ID
import net.corda.testing.dummyCommand import net.corda.testing.dummyCommand
import net.corda.testing.getDefaultNotary
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import org.junit.After import org.junit.After
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
@ -64,8 +65,7 @@ class ScheduledFlowTests {
@Suspendable @Suspendable
override fun call() { override fun call() {
val scheduledState = ScheduledState(serviceHub.clock.instant(), ourIdentity, destination) val scheduledState = ScheduledState(serviceHub.clock.instant(), ourIdentity, destination)
val notary = serviceHub.getDefaultNotary()
val notary = serviceHub.networkMapCache.getAnyNotary()
val builder = TransactionBuilder(notary) val builder = TransactionBuilder(notary)
.addOutputState(scheduledState, DUMMY_PROGRAM_ID) .addOutputState(scheduledState, DUMMY_PROGRAM_ID)
.addCommand(dummyCommand(ourIdentity.owningKey)) .addCommand(dummyCommand(ourIdentity.owningKey))

View File

@ -45,7 +45,7 @@ class BankOfCordaRPCClientTest {
// Kick-off actual Issuer Flow // Kick-off actual Issuer Flow
val anonymous = true val anonymous = true
val notary = bocProxy.notaryIdentities().first().party val notary = bocProxy.notaryIdentities().first()
bocProxy.startFlow(::CashIssueAndPaymentFlow, bocProxy.startFlow(::CashIssueAndPaymentFlow,
1000.DOLLARS, BIG_CORP_PARTY_REF, 1000.DOLLARS, BIG_CORP_PARTY_REF,
nodeBigCorporation.nodeInfo.chooseIdentity(), nodeBigCorporation.nodeInfo.chooseIdentity(),

View File

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

View File

@ -54,7 +54,7 @@ object UpdateBusinessDayFlow {
* the notary or counterparty still use the old clock, so the time-window on the transaction does not validate. * the notary or counterparty still use the old clock, so the time-window on the transaction does not validate.
*/ */
private fun getRecipients(): Iterable<Party> { private fun getRecipients(): Iterable<Party> {
val notaryParties = serviceHub.networkMapCache.notaryIdentities.map { it.party } val notaryParties = serviceHub.networkMapCache.notaryIdentities
val peerParties = serviceHub.networkMapCache.allNodes.filter { val peerParties = serviceHub.networkMapCache.allNodes.filter {
it.legalIdentities.all { !serviceHub.networkMapCache.isNotary(it) } it.legalIdentities.all { !serviceHub.networkMapCache.isNotary(it) }
}.map { it.legalIdentities[0] }.sortedBy { it.name.toString() } }.map { it.legalIdentities[0] }.sortedBy { it.name.toString() }

View File

@ -138,7 +138,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten
node1.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java) node1.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java)
node2.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java) node2.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java)
val notaryId = node1.rpcOps.notaryIdentities().first().party val notaryId = node1.rpcOps.notaryIdentities().first()
@InitiatingFlow @InitiatingFlow
class StartDealFlow(val otherParty: Party, class StartDealFlow(val otherParty: Party,
val payload: AutoOffer) : FlowLogic<SignedTransaction>() { val payload: AutoOffer) : FlowLogic<SignedTransaction>() {

View File

@ -5,7 +5,6 @@ import net.corda.core.crypto.toStringShort
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.node.NodeInfo
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
@ -13,7 +12,6 @@ import net.corda.notarydemo.flows.DummyIssueAndMove
import net.corda.notarydemo.flows.RPCStartableNotaryFlowClient import net.corda.notarydemo.flows.RPCStartableNotaryFlowClient
import net.corda.testing.BOB import net.corda.testing.BOB
import java.util.concurrent.Future import java.util.concurrent.Future
import kotlin.streams.asSequence
fun main(args: Array<String>) { fun main(args: Array<String>) {
val address = NetworkHostAndPort("localhost", 10003) val address = NetworkHostAndPort("localhost", 10003)
@ -26,7 +24,7 @@ fun main(args: Array<String>) {
/** Interface for using the notary demo API from a client. */ /** Interface for using the notary demo API from a client. */
private class NotaryDemoClientApi(val rpc: CordaRPCOps) { private class NotaryDemoClientApi(val rpc: CordaRPCOps) {
private val notary by lazy { private val notary by lazy {
val id = rpc.notaryIdentities().distinct().singleOrNull()?.party val id = rpc.notaryIdentities().singleOrNull()
checkNotNull(id) { "No unique notary identity, try cleaning the node directories." } checkNotNull(id) { "No unique notary identity, try cleaning the node directories." }
} }

View File

@ -254,7 +254,7 @@ class PortfolioApi(val rpc: CordaRPCOps) {
val parties = rpc.networkMapSnapshot() val parties = rpc.networkMapSnapshot()
val notaries = rpc.notaryIdentities() val notaries = rpc.notaryIdentities()
// TODO We are not able to filter by network map node now // TODO We are not able to filter by network map node now
val counterParties = parties.filterNot { it.legalIdentitiesAndCerts.any { it in notaries } val counterParties = parties.filterNot { it.legalIdentities.any { it in notaries }
|| ownParty in it.legalIdentities || ownParty in it.legalIdentities
} }
return AvailableParties( return AvailableParties(

View File

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

View File

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

View File

@ -18,7 +18,6 @@ import net.corda.finance.contracts.getCashBalance
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.vault.VaultSchemaV1 import net.corda.node.services.vault.VaultSchemaV1
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.contracts.calculateRandomlySizedAmounts import net.corda.testing.contracts.calculateRandomlySizedAmounts
import net.corda.traderdemo.flow.CommercialPaperIssueFlow import net.corda.traderdemo.flow.CommercialPaperIssueFlow
import net.corda.traderdemo.flow.SellerFlow import net.corda.traderdemo.flow.SellerFlow
@ -46,7 +45,7 @@ class TraderDemoClientApi(val rpc: CordaRPCOps) {
val ref = OpaqueBytes.of(1) val ref = OpaqueBytes.of(1)
val buyer = rpc.partyFromX500Name(buyerName) ?: throw IllegalStateException("Don't know $buyerName") val buyer = rpc.partyFromX500Name(buyerName) ?: throw IllegalStateException("Don't know $buyerName")
val seller = rpc.partyFromX500Name(sellerName) ?: throw IllegalStateException("Don't know $sellerName") val seller = rpc.partyFromX500Name(sellerName) ?: throw IllegalStateException("Don't know $sellerName")
val notaryIdentity = rpc.notaryIdentities().first().party val notaryIdentity = rpc.notaryIdentities().first()
val amounts = calculateRandomlySizedAmounts(amount, 3, 10, Random()) val amounts = calculateRandomlySizedAmounts(amount, 3, 10, Random())
rpc.startFlow(::CashIssueFlow, amount, OpaqueBytes.of(1), notaryIdentity).returnValue.getOrThrow() rpc.startFlow(::CashIssueFlow, amount, OpaqueBytes.of(1), notaryIdentity).returnValue.getOrThrow()

View File

@ -6,7 +6,6 @@ import net.corda.core.flows.FlowLogic
import net.corda.core.flows.InitiatedBy import net.corda.core.flows.InitiatedBy
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.Emoji import net.corda.core.internal.Emoji
import net.corda.core.node.NodeInfo
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
import net.corda.core.utilities.unwrap import net.corda.core.utilities.unwrap
@ -30,7 +29,7 @@ class BuyerFlow(val otherParty: Party) : FlowLogic<Unit>() {
// Receive the offered amount and automatically agree to it (in reality this would be a longer negotiation) // Receive the offered amount and automatically agree to it (in reality this would be a longer negotiation)
val amount = receive<Amount<Currency>>(otherParty).unwrap { it } val amount = receive<Amount<Currency>>(otherParty).unwrap { it }
require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" } require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" }
val notary: Party = serviceHub.networkMapCache.notaryIdentities[0].party val notary: Party = serviceHub.networkMapCache.notaryIdentities.first()
val buyer = TwoPartyTradeFlow.Buyer( val buyer = TwoPartyTradeFlow.Buyer(
otherParty, otherParty,
notary, notary,
@ -59,7 +58,7 @@ class BuyerFlow(val otherParty: Party) : FlowLogic<Unit>() {
// the state. // the state.
val search = TransactionGraphSearch(serviceHub.validatedTransactions, listOf(tradeTX.tx), val search = TransactionGraphSearch(serviceHub.validatedTransactions, listOf(tradeTX.tx),
TransactionGraphSearch.Query(withCommandOfType = CommercialPaper.Commands.Issue::class.java, TransactionGraphSearch.Query(withCommandOfType = CommercialPaper.Commands.Issue::class.java,
followInputsOfType = CommercialPaper.State::class.java)) followInputsOfType = CommercialPaper.State::class.java))
val cpIssuance = search.call().single() val cpIssuance = search.call().single()
// Buyer will fetch the attachment from the seller automatically when it resolves the transaction. // Buyer will fetch the attachment from the seller automatically when it resolves the transaction.

View File

@ -7,7 +7,6 @@ import net.corda.core.flows.FlowLogic
import net.corda.core.flows.InitiatingFlow import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.StartableByRPC import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.node.NodeInfo
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
import net.corda.finance.contracts.CommercialPaper import net.corda.finance.contracts.CommercialPaper
@ -40,7 +39,6 @@ class SellerFlow(private val otherParty: Party,
override fun call(): SignedTransaction { override fun call(): SignedTransaction {
progressTracker.currentStep = SELF_ISSUING progressTracker.currentStep = SELF_ISSUING
val notary: Party = serviceHub.networkMapCache.notaryIdentities[0].party
val cpOwner = serviceHub.keyManagementService.freshKeyAndCert(ourIdentityAndCert, false) val cpOwner = serviceHub.keyManagementService.freshKeyAndCert(ourIdentityAndCert, false)
val commercialPaper = serviceHub.vaultQueryService.queryBy(CommercialPaper.State::class.java).states.first() val commercialPaper = serviceHub.vaultQueryService.queryBy(CommercialPaper.State::class.java).states.first()

View File

@ -163,5 +163,5 @@ inline fun <reified T : Any> amqpSpecific(reason: String, function: () -> Unit)
*/ */
fun NodeInfo.chooseIdentityAndCert(): PartyAndCertificate = legalIdentitiesAndCerts.first() fun NodeInfo.chooseIdentityAndCert(): PartyAndCertificate = legalIdentitiesAndCerts.first()
fun NodeInfo.chooseIdentity(): Party = chooseIdentityAndCert().party fun NodeInfo.chooseIdentity(): Party = chooseIdentityAndCert().party
/** Returns the identity of the first notary found on the network */
fun ServiceHub.getDefaultNotary(): Party = networkMapCache.notaryIdentities.first().party fun ServiceHub.getDefaultNotary(): Party = networkMapCache.notaryIdentities.first()

View File

@ -173,7 +173,7 @@ class ExplorerSimulation(val options: OptionSet) {
private fun startNormalSimulation() { private fun startNormalSimulation() {
println("Running simulation mode ...") println("Running simulation mode ...")
setUpRPC() setUpRPC()
notary = aliceNode.rpc.notaryIdentities().first().party notary = aliceNode.rpc.notaryIdentities().first()
val eventGenerator = EventGenerator( val eventGenerator = EventGenerator(
parties = parties.map { it.first }, parties = parties.map { it.first },
notary = notary, notary = notary,

View File

@ -156,7 +156,7 @@ class NewTransaction : Fragment() {
val issueRef = if (issueRef.value != null) OpaqueBytes.of(issueRef.value) else defaultRef val issueRef = if (issueRef.value != null) OpaqueBytes.of(issueRef.value) else defaultRef
when (it) { when (it) {
executeButton -> when (transactionTypeCB.value) { executeButton -> when (transactionTypeCB.value) {
CashTransaction.Issue -> IssueAndPaymentRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), issueRef, partyBChoiceBox.value.party, notaries.first().party, anonymous) CashTransaction.Issue -> IssueAndPaymentRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), issueRef, partyBChoiceBox.value.party, notaries.first(), anonymous)
CashTransaction.Pay -> PaymentRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), partyBChoiceBox.value.party, anonymous = anonymous) CashTransaction.Pay -> PaymentRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), partyBChoiceBox.value.party, anonymous = anonymous)
CashTransaction.Exit -> ExitRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), issueRef) CashTransaction.Exit -> ExitRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), issueRef)
else -> null else -> null

View File

@ -1,7 +1,6 @@
package net.corda.loadtest package net.corda.loadtest
import net.corda.client.mock.* import net.corda.client.mock.*
import net.corda.node.services.network.NetworkMapService
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.util.* import java.util.*
import java.util.concurrent.Callable import java.util.concurrent.Callable
@ -44,7 +43,7 @@ data class DisruptionSpec(
*/ */
val isNotary = { node: NodeConnection -> val isNotary = { node: NodeConnection ->
val notaries = node.proxy.notaryIdentities() val notaries = node.proxy.notaryIdentities()
node.info.legalIdentitiesAndCerts.any { it in notaries } node.info.legalIdentities.any { it in notaries }
} }
fun <A> ((A) -> Boolean).or(other: (A) -> Boolean): (A) -> Boolean = { this(it) || other(it) } fun <A> ((A) -> Boolean).or(other: (A) -> Boolean): (A) -> Boolean = { this(it) || other(it) }

View File

@ -3,7 +3,6 @@ package net.corda.loadtest
import com.google.common.util.concurrent.RateLimiter import com.google.common.util.concurrent.RateLimiter
import net.corda.client.mock.Generator import net.corda.client.mock.Generator
import net.corda.core.utilities.toBase58String import net.corda.core.utilities.toBase58String
import net.corda.node.services.network.NetworkMapService
import net.corda.testing.driver.PortAllocation import net.corda.testing.driver.PortAllocation
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.util.* import java.util.*
@ -195,7 +194,7 @@ fun runLoadTests(configuration: LoadTestConfiguration, tests: List<Pair<LoadTest
val networkMapNode = hostNodeMap[networkMap]!! val networkMapNode = hostNodeMap[networkMap]!!
val notaryIdentity = networkMapNode.proxy.notaryIdentities().single() val notaryIdentity = networkMapNode.proxy.notaryIdentities().single()
val notaryNode = hostNodeMap.values.single { notaryIdentity in it.info.legalIdentitiesAndCerts } val notaryNode = hostNodeMap.values.single { notaryIdentity in it.info.legalIdentities }
val nodes = Nodes( val nodes = Nodes(
notary = notaryNode, notary = notaryNode,
networkMap = networkMapNode, networkMap = networkMapNode,

View File

@ -123,7 +123,7 @@ val crossCashTest = LoadTest<CrossCashCommand, CrossCashState>(
generate = { (nodeVaults), parallelism -> generate = { (nodeVaults), parallelism ->
val nodeMap = simpleNodes.associateBy { it.mainIdentity } val nodeMap = simpleNodes.associateBy { it.mainIdentity }
val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first().party val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first()
Generator.pickN(parallelism, simpleNodes).flatMap { nodes -> Generator.pickN(parallelism, simpleNodes).flatMap { nodes ->
Generator.sequence( Generator.sequence(
nodes.map { node -> nodes.map { node ->

View File

@ -36,7 +36,7 @@ val selfIssueTest = LoadTest<SelfIssueCommand, SelfIssueState>(
// DOCS END 1 // DOCS END 1
"Self issuing cash randomly", "Self issuing cash randomly",
generate = { _, parallelism -> generate = { _, parallelism ->
val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first().party val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first()
val generateIssue = Generator.pickOne(simpleNodes).flatMap { node -> val generateIssue = Generator.pickOne(simpleNodes).flatMap { node ->
generateIssue(1000, USD, notaryIdentity, listOf(node.mainIdentity)).map { generateIssue(1000, USD, notaryIdentity, listOf(node.mainIdentity)).map {
SelfIssueCommand(it, node) SelfIssueCommand(it, node)

View File

@ -49,7 +49,7 @@ object StabilityTest {
fun selfIssueTest(replication: Int) = LoadTest<SelfIssueCommand, Unit>( fun selfIssueTest(replication: Int) = LoadTest<SelfIssueCommand, Unit>(
"Self issuing lot of cash", "Self issuing lot of cash",
generate = { _, _ -> generate = { _, _ ->
val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first().party val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first()
// Self issue cash is fast, its ok to flood the node with this command. // Self issue cash is fast, its ok to flood the node with this command.
val generateIssue = val generateIssue =
simpleNodes.map { issuer -> simpleNodes.map { issuer ->