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.map
import net.corda.core.identity.AnonymousParty
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.MapChange
@ -36,9 +37,9 @@ class NetworkIdentityModel {
publicKey?.let { rpcProxy.map { it?.nodeInfoFromParty(AnonymousParty(publicKey)) } }
})
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 notaries: ObservableList<Party> = FXCollections.observableList(rpcProxy.value?.notaryIdentities())
val notaryNodes: ObservableList<NodeInfo> = FXCollections.observableList(notaries.map { rpcProxy.value?.nodeInfoFromParty(it) })
val parties: ObservableList<NodeInfo> = networkIdentities.filtered { it.legalIdentities.all { it !in notaries } }
val myIdentity = rpcProxy.map { it?.nodeInfo()?.legalIdentitiesAndCerts?.first()?.party }
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.core.contracts.ContractState
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.node.services.NetworkMapCache.MapChange
import net.corda.core.node.services.Vault
@ -46,7 +46,7 @@ class NodeMonitorModel {
val networkMap: Observable<MapChange> = networkMapSubject
val proxyObservable = SimpleObjectProperty<CordaRPCOps?>()
lateinit var notaryIdentities: List<PartyAndCertificate>
lateinit var notaryIdentities: List<Party>
/**
* 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.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
@ -59,13 +58,12 @@ interface CordaRPCOps : RPCOps {
*/
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>
/**
* 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
fun stateMachinesFeed(): DataFeed<List<StateMachineInfo>, StateMachineUpdate>
@ -172,9 +170,7 @@ interface CordaRPCOps : RPCOps {
@RPCReturnsObservables
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>
/**
@ -184,19 +180,19 @@ interface CordaRPCOps : RPCOps {
@RPCReturnsObservables
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>
/**
* 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
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
fun <T> startFlowDynamic(logicType: Class<out FlowLogic<T>>, vararg args: Any?): FlowHandle<T>
@ -208,44 +204,32 @@ interface CordaRPCOps : RPCOps {
@RPCReturnsObservables
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
/**
* 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)
/*
* Retrieve existing note(s) for a given Vault transaction
*/
/** Retrieve existing note(s) for a given Vault transaction. */
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
/**
* Download an attachment JAR by ID
*/
/** Download an attachment JAR by ID. */
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
/**
* Returns the node's current time.
*/
/** Returns the node's current time. */
fun currentNodeTime(): Instant
/**
@ -266,14 +250,10 @@ interface CordaRPCOps : RPCOps {
* @return well known identity, if found.
*/
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?
/**
* 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?
/**
@ -296,9 +276,7 @@ interface CordaRPCOps : RPCOps {
*/
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()
}

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.
* 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
* that may be necessary for the service. Corda services are created as singletons within the node and are available
* to flows via [ServiceHub.cordaService].

View File

@ -1,12 +1,9 @@
package net.corda.core.node.services
import net.corda.core.concurrent.CordaFuture
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.serialization.CordaSerializable
@ -31,10 +28,14 @@ interface NetworkMapCache {
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.
val notaryIdentities: List<PartyAndCertificate>
/** Tracks changes to the network map cache */
val notaryIdentities: List<Party>
/** Tracks changes to the network map cache. */
val changed: Observable<MapChange>
/** Future to track completion of the NetworkMapService registration. */
val nodeReady: CordaFuture<Void?>
@ -66,7 +67,7 @@ interface NetworkMapCache {
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>
/**
@ -81,25 +82,17 @@ interface NetworkMapCache {
fun getPartyInfo(party: Party): PartyInfo?
/** 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 }
/**
* 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(): Party? = notaryIdentities.randomOrNull()?.party
/** Checks whether a given party is an advertised notary identity. */
fun isNotary(party: Party): Boolean = party in notaryIdentities
/** Checks whether a given party is an advertised notary identity */
fun isNotary(party: Party): Boolean = notaryIdentities.any { party == it.party }
/** Checks whether a given party is an validating notary identity */
/** Checks whether a given party is an validating notary identity. */
fun isValidatingNotary(party: Party): Boolean {
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.
require(isNotary(party)) { "No notary found with identity $party." }
return !party.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()
}

View File

@ -18,7 +18,7 @@ UNRELEASED
* 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``,
``getNodesWithService``, ``getPeersWithService``, ``getRecommended``, ``getNodesByAdvertisedServiceIdentityKey``, ``getAnyNotary``,
``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``

View File

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

View File

@ -125,11 +125,10 @@ 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();
// 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().getNotaryIdentities().get(0).getParty();
// Alternatively, we can pick an arbitrary notary from the notary list. However, it is always preferable to
// specify which notary to use explicitly, as the notary list might change when new notaries are introduced,
// or old ones decommissioned.
Party firstNotary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
// DOCEND 1
// 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
}
val issueRef = OpaqueBytes.of(0)
val notary = proxy.notaryIdentities().first().party
val notary = proxy.notaryIdentities().first()
val me = proxy.nodeInfo().legalIdentities.first()
while (true) {
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.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow
import net.corda.testing.getDefaultNotary
import java.util.*
// DOCSTART CustomVaultQuery
@ -133,7 +132,8 @@ object TopupIssuerFlow {
issueTo: Party,
issuerPartyRef: OpaqueBytes): AbstractCashFlow.Result {
// 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
progressTracker.currentStep = ISSUING
val issueCashFlow = CashIssueFlow(amount, issuerPartyRef, notaryParty)

View File

@ -104,11 +104,10 @@ object FlowCookbook {
// We retrieve the notary from the network map.
// DOCSTART 1
val specificNotary: Party? = serviceHub.networkMapCache.getNotary(CordaX500Name(organisation = "Notary Service", locality = "London", country = "UK"))
val anyNotary: Party? = serviceHub.networkMapCache.getAnyNotary()
// 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.notaryIdentities[0].party
// Alternatively, we can pick an arbitrary notary from the notary list. However, it is always preferable to
// specify which notary to use explicitly, as the notary list might change when new notaries are introduced,
// or old ones decommissioned.
val firstNotary: Party = serviceHub.networkMapCache.notaryIdentities.first()
// DOCEND 1
// 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 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 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.utilities.seconds
import net.corda.core.utilities.unwrap
import net.corda.testing.chooseIdentity
// Minimal state model of a manual approval process
@CordaSerializable
@ -102,7 +101,7 @@ class SubmitTradeApprovalFlow(private val tradeId: String,
// Manufacture an initial state
val tradeProposal = TradeApprovalContract.State(tradeId, ourIdentity, counterparty)
// 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.
val tx = TransactionBuilder(notary).withItems(
StateAndContract(tradeProposal, TRADE_APPROVAL_PROGRAM_ID),

View File

@ -110,7 +110,7 @@ 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
val notary = connection.proxy.notaryIdentities().first()
println("ISSUING")
val doneFutures = (1..100).toList().parallelStream().map {
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.internal.concurrent.transpose
import net.corda.core.internal.elapsedTime
import net.corda.core.internal.randomOrNull
import net.corda.core.internal.times
import net.corda.core.messaging.MessageRecipients
import net.corda.core.messaging.SingleMessageRecipient
@ -55,7 +56,8 @@ class P2PMessagingTest : NodeBasedTest() {
networkMapNode.respondWith("Hello")
val alice = startNode(ALICE.name).getOrThrow()
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)
assertThat(received).isEqualTo("Hello")
@ -100,7 +102,8 @@ class P2PMessagingTest : NodeBasedTest() {
val distributedServiceNodes = startNotaryCluster(DISTRIBUTED_SERVICE_NAME, 2).getOrThrow()
val alice = startNode(ALICE.name, configOverrides = mapOf("messageRedeliveryDelaySeconds" to 1)).getOrThrow()
val serviceAddress = alice.services.networkMapCache.run {
alice.network.getAddressOfParty(getPartyInfo(getAnyNotary()!!)!!)
val notaryParty = notaryIdentities.randomOrNull()!!
alice.network.getAddressOfParty(getPartyInfo(notaryParty)!!)
}
val dummyTopic = "dummy.topic"
@ -131,7 +134,8 @@ class P2PMessagingTest : NodeBasedTest() {
val distributedServiceNodes = startNotaryCluster(DISTRIBUTED_SERVICE_NAME, 2).getOrThrow()
val alice = startNode(ALICE.name, configOverrides = mapOf("messageRedeliveryDelaySeconds" to 1)).getOrThrow()
val serviceAddress = alice.services.networkMapCache.run {
alice.network.getAddressOfParty(getPartyInfo(getAnyNotary()!!)!!)
val notaryParty = notaryIdentities.randomOrNull()!!
alice.network.getAddressOfParty(getPartyInfo(notaryParty)!!)
}
val dummyTopic = "dummy.topic"

View File

@ -136,7 +136,7 @@ class SendMessageFlow(private val message: Message) : FlowLogic<SignedTransactio
@Suspendable
override fun call(): SignedTransaction {
val notary = serviceHub.networkMapCache.getAnyNotary()
val notary = serviceHub.networkMapCache.notaryIdentities.first()
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.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
@ -115,7 +114,7 @@ class CordaRPCOpsImpl(
return services.myInfo
}
override fun notaryIdentities(): List<PartyAndCertificate> {
override fun notaryIdentities(): List<Party> {
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.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
@ -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.
// 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.
}
override val notaryIdentities: List<Party>
get() {
return partyNodes
.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 {
serviceHub.database.transaction { loadFromDB() }
@ -127,9 +135,9 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
data = NetworkMapService.UpdateAcknowledge(req.mapVersion, network.myAddress).serialize().bytes)
network.send(ackMessage, req.replyTo)
processUpdatePush(req)
} catch(e: NodeMapError) {
} catch (e: NodeMapError) {
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)
}
}
@ -183,7 +191,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
// Fetch the network map and register for updates at the same time
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.
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")
val future = network.sendRequest<SubscribeResponse>(NetworkMapService.SUBSCRIPTION_TOPIC, req, address).map {
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 {
createSession {
getAllInfos(it).map { it.toNodeInfo() }
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
@ -333,7 +342,8 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
addresses = nodeInfo.addresses.map { NodeInfoSchemaV1.DBHostAndPort.fromHostAndPort(it) },
// TODO Another ugly hack with special first identity...
legalIdentitiesAndCerts = nodeInfo.legalIdentitiesAndCerts.mapIndexed { idx, elem ->
NodeInfoSchemaV1.DBPartyAndCertificate(elem, isMain = idx == 0) },
NodeInfoSchemaV1.DBPartyAndCertificate(elem, isMain = idx == 0)
},
platformVersion = nodeInfo.platformVersion,
serial = nodeInfo.serial
)

View File

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

View File

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

View File

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

View File

@ -48,7 +48,7 @@ object AutoOfferFlow {
@Suspendable
override fun call(): SignedTransaction {
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
val otherParty = notUs(dealToBeOffered.participants).map { serviceHub.identityService.partyFromAnonymous(it) }.requireNoNulls().single()
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.
*/
private fun getRecipients(): Iterable<Party> {
val notaryParties = serviceHub.networkMapCache.notaryIdentities.map { it.party }
val notaryParties = serviceHub.networkMapCache.notaryIdentities
val peerParties = serviceHub.networkMapCache.allNodes.filter {
it.legalIdentities.all { !serviceHub.networkMapCache.isNotary(it) }
}.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)
node2.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java)
val notaryId = node1.rpcOps.notaryIdentities().first().party
val notaryId = node1.rpcOps.notaryIdentities().first()
@InitiatingFlow
class StartDealFlow(val otherParty: Party,
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.messaging.CordaRPCOps
import net.corda.core.messaging.startFlow
import net.corda.core.node.NodeInfo
import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.NetworkHostAndPort
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.testing.BOB
import java.util.concurrent.Future
import kotlin.streams.asSequence
fun main(args: Array<String>) {
val address = NetworkHostAndPort("localhost", 10003)
@ -26,7 +24,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 id = rpc.notaryIdentities().distinct().singleOrNull()?.party
val id = rpc.notaryIdentities().singleOrNull()
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 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 }
val counterParties = parties.filterNot { it.legalIdentities.any { it in notaries }
|| ownParty in it.legalIdentities
}
return AvailableParties(

View File

@ -23,7 +23,7 @@ object IRSTradeFlow {
@Suspendable
override fun call(): SignedTransaction {
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) =
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.notaryIdentities.map { it.party }.contains(offer.notary))
require(serviceHub.networkMapCache.notaryIdentities.contains(offer.notary))
send(replyToParty, true)
subFlow(TwoPartyDealFlow.Acceptor(replyToParty))
}

View File

@ -62,7 +62,7 @@ object SimmFlow {
override fun call(): RevisionedState<PortfolioState.Update> {
logger.debug("Calling from: $ourIdentity. Sending to: $otherParty")
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 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.CashPaymentFlow
import net.corda.node.services.vault.VaultSchemaV1
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.contracts.calculateRandomlySizedAmounts
import net.corda.traderdemo.flow.CommercialPaperIssueFlow
import net.corda.traderdemo.flow.SellerFlow
@ -46,7 +45,7 @@ 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 notaryIdentity = rpc.notaryIdentities().first().party
val notaryIdentity = rpc.notaryIdentities().first()
val amounts = calculateRandomlySizedAmounts(amount, 3, 10, Random())
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.identity.Party
import net.corda.core.internal.Emoji
import net.corda.core.node.NodeInfo
import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.ProgressTracker
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)
val amount = receive<Amount<Currency>>(otherParty).unwrap { it }
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(
otherParty,
notary,
@ -59,7 +58,7 @@ class BuyerFlow(val otherParty: Party) : FlowLogic<Unit>() {
// the state.
val search = TransactionGraphSearch(serviceHub.validatedTransactions, listOf(tradeTX.tx),
TransactionGraphSearch.Query(withCommandOfType = CommercialPaper.Commands.Issue::class.java,
followInputsOfType = CommercialPaper.State::class.java))
followInputsOfType = CommercialPaper.State::class.java))
val cpIssuance = search.call().single()
// 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.StartableByRPC
import net.corda.core.identity.Party
import net.corda.core.node.NodeInfo
import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.ProgressTracker
import net.corda.finance.contracts.CommercialPaper
@ -40,7 +39,6 @@ class SellerFlow(private val otherParty: Party,
override fun call(): SignedTransaction {
progressTracker.currentStep = SELF_ISSUING
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()

View File

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

View File

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

View File

@ -156,7 +156,7 @@ class NewTransaction : Fragment() {
val issueRef = if (issueRef.value != null) OpaqueBytes.of(issueRef.value) else defaultRef
when (it) {
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.Exit -> ExitRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), issueRef)
else -> null

View File

@ -1,7 +1,6 @@
package net.corda.loadtest
import net.corda.client.mock.*
import net.corda.node.services.network.NetworkMapService
import org.slf4j.LoggerFactory
import java.util.*
import java.util.concurrent.Callable
@ -44,7 +43,7 @@ data class DisruptionSpec(
*/
val isNotary = { node: NodeConnection ->
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) }

View File

@ -3,7 +3,6 @@ package net.corda.loadtest
import com.google.common.util.concurrent.RateLimiter
import net.corda.client.mock.Generator
import net.corda.core.utilities.toBase58String
import net.corda.node.services.network.NetworkMapService
import net.corda.testing.driver.PortAllocation
import org.slf4j.LoggerFactory
import java.util.*
@ -195,7 +194,7 @@ fun runLoadTests(configuration: LoadTestConfiguration, tests: List<Pair<LoadTest
val networkMapNode = hostNodeMap[networkMap]!!
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(
notary = notaryNode,
networkMap = networkMapNode,

View File

@ -123,7 +123,7 @@ val crossCashTest = LoadTest<CrossCashCommand, CrossCashState>(
generate = { (nodeVaults), parallelism ->
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.sequence(
nodes.map { node ->

View File

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

View File

@ -49,7 +49,7 @@ object StabilityTest {
fun selfIssueTest(replication: Int) = LoadTest<SelfIssueCommand, Unit>(
"Self issuing lot of cash",
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.
val generateIssue =
simpleNodes.map { issuer ->