mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
Cleaned up NodeInfo API (#1535)
This commit is contained in:
parent
2c5aa4eead
commit
4c40c764c3
@ -132,9 +132,8 @@ class NodeMonitorModelTest : DriverBasedTest() {
|
||||
|
||||
@Test
|
||||
fun `cash issue and move`() {
|
||||
val anonymous = false
|
||||
val (_, issueIdentity) = rpc.startFlow(::CashIssueFlow, 100.DOLLARS, OpaqueBytes.of(1), notaryNode.notaryIdentity).returnValue.getOrThrow()
|
||||
val (_, paymentIdentity) = rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, bobNode.chooseIdentity()).returnValue.getOrThrow()
|
||||
rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, bobNode.chooseIdentity()).returnValue.getOrThrow()
|
||||
|
||||
var issueSmId: StateMachineRunId? = null
|
||||
var moveSmId: StateMachineRunId? = null
|
||||
@ -152,7 +151,7 @@ class NodeMonitorModelTest : DriverBasedTest() {
|
||||
require(remove.id == issueSmId)
|
||||
},
|
||||
// MOVE - N.B. There are other framework flows that happen in parallel for the remote resolve transactions flow
|
||||
expect(match = { it is StateMachineUpdate.Added && it.stateMachineInfo.flowLogicClassName == CashPaymentFlow::class.java.name }) { add: StateMachineUpdate.Added ->
|
||||
expect(match = { it.stateMachineInfo.flowLogicClassName == CashPaymentFlow::class.java.name }) { add: StateMachineUpdate.Added ->
|
||||
moveSmId = add.id
|
||||
val initiator = add.stateMachineInfo.initiator
|
||||
require(initiator is FlowInitiator.RPC && initiator.username == "user1")
|
||||
@ -167,7 +166,7 @@ class NodeMonitorModelTest : DriverBasedTest() {
|
||||
// MOVE
|
||||
expect { add: StateMachineUpdate.Added ->
|
||||
val initiator = add.stateMachineInfo.initiator
|
||||
require(initiator is FlowInitiator.Peer && initiator.party.name == aliceNode.chooseIdentity().name)
|
||||
require(initiator is FlowInitiator.Peer && aliceNode.isLegalIdentity(initiator.party))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -2,7 +2,10 @@ package net.corda.client.rpc
|
||||
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.flows.FlowInitiator
|
||||
import net.corda.core.messaging.*
|
||||
import net.corda.core.messaging.FlowProgressHandle
|
||||
import net.corda.core.messaging.StateMachineUpdate
|
||||
import net.corda.core.messaging.startFlow
|
||||
import net.corda.core.messaging.startTrackedFlow
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
@ -105,7 +108,6 @@ class CordaRPCClientTest : NodeBasedTest() {
|
||||
login(rpcUser.username, rpcUser.password)
|
||||
connection!!.proxy.startFlow(::CashPaymentFlow, 100.DOLLARS, node.info.chooseIdentity()).use {
|
||||
assertFalse(it is FlowProgressHandle<*>)
|
||||
assertTrue(it is FlowHandle<*>)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ class BroadcastTransactionFlow(val notarisedTransaction: SignedTransaction,
|
||||
@Suspendable
|
||||
override fun call() {
|
||||
// TODO: Messaging layer should handle this broadcast for us
|
||||
participants.filter { it !in serviceHub.myInfo.legalIdentities }.forEach { participant ->
|
||||
participants.filter { !serviceHub.myInfo.isLegalIdentity(it) }.forEach { participant ->
|
||||
// SendTransactionFlow allows otherParty to access our data to resolve the transaction.
|
||||
subFlow(SendTransactionFlow(participant, notarisedTransaction))
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ package net.corda.core.flows
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.node.services.IdentityService
|
||||
import net.corda.core.utilities.ProgressTracker
|
||||
import net.corda.core.utilities.unwrap
|
||||
@ -40,7 +40,7 @@ class SwapIdentitiesFlow(val otherSide: Party,
|
||||
|
||||
// Special case that if we're both parties, a single identity is generated
|
||||
val identities = LinkedHashMap<Party, AnonymousParty>()
|
||||
if (otherSide in serviceHub.myInfo.legalIdentities) {
|
||||
if (serviceHub.myInfo.isLegalIdentity(otherSide)) {
|
||||
identities.put(otherSide, legalIdentityAnonymous.party.anonymise())
|
||||
} else {
|
||||
val anonymousOtherSide = sendAndReceive<PartyAndCertificate>(otherSide, legalIdentityAnonymous).unwrap { confidentialIdentity ->
|
||||
|
@ -18,10 +18,9 @@ data class ServiceEntry(val info: ServiceInfo, val identity: PartyAndCertificate
|
||||
* Info about a network node that acts on behalf of some form of contract party.
|
||||
*/
|
||||
// TODO We currently don't support multi-IP/multi-identity nodes, we only left slots in the data structures.
|
||||
// Note that order of `legalIdentitiesAndCerts` is now important. We still treat the first identity as a special one.
|
||||
// It will change after introducing proper multi-identity management.
|
||||
@CordaSerializable
|
||||
data class NodeInfo(val addresses: List<NetworkHostAndPort>,
|
||||
/** Non-empty list of all the identities, plus certificates, that belong to this node. */
|
||||
val legalIdentitiesAndCerts: List<PartyAndCertificate>,
|
||||
val platformVersion: Int,
|
||||
val advertisedServices: List<ServiceEntry> = emptyList(),
|
||||
@ -33,17 +32,16 @@ data class NodeInfo(val addresses: List<NetworkHostAndPort>,
|
||||
|
||||
// TODO This part will be removed with services removal.
|
||||
val notaryIdentity: Party get() = advertisedServices.single { it.info.type.isNotary() }.identity.party
|
||||
|
||||
@Transient private var _legalIdentities: List<Party>? = null
|
||||
val legalIdentities: List<Party> get() {
|
||||
return _legalIdentities ?: legalIdentitiesAndCerts.map { it.party }.also { _legalIdentities = it }
|
||||
}
|
||||
|
||||
/** Returns true iff [party] is one of the identities of this node. */
|
||||
fun isLegalIdentity(party: Party): Boolean = party in legalIdentities
|
||||
|
||||
fun serviceIdentities(type: ServiceType): List<Party> {
|
||||
return advertisedServices.mapNotNull { if (it.info.type.isSubTypeOf(type)) it.identity.party else null }
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses node's owner X500 name to infer the node's location. Used in Explorer in map view.
|
||||
*/
|
||||
fun getWorldMapLocation(): WorldMapLocation? {
|
||||
val nodeOwnerLocation = legalIdentitiesAndCerts.first().name.locality
|
||||
return nodeOwnerLocation.let { CityDatabase[it] }
|
||||
}
|
||||
val legalIdentities: List<Party>
|
||||
get() = legalIdentitiesAndCerts.map { it.party }
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import co.paralleluniverse.fibers.Suspendable;
|
||||
import com.google.common.primitives.Primitives;
|
||||
import net.corda.core.identity.Party;
|
||||
import net.corda.node.internal.StartedNode;
|
||||
import net.corda.testing.CoreTestUtils;
|
||||
import net.corda.testing.node.MockNetwork;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@ -13,6 +12,7 @@ import org.junit.Test;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import static net.corda.testing.CoreTestUtils.chooseIdentity;
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@ -40,7 +40,7 @@ public class FlowsInJavaTest {
|
||||
@Test
|
||||
public void suspendableActionInsideUnwrap() throws Exception {
|
||||
node2.getInternals().registerInitiatedFlow(SendHelloAndThenReceive.class);
|
||||
Future<String> result = node1.getServices().startFlow(new SendInUnwrapFlow(CoreTestUtils.chooseIdentity(node2.getInfo()))).getResultFuture();
|
||||
Future<String> result = node1.getServices().startFlow(new SendInUnwrapFlow(chooseIdentity(node2.getInfo()))).getResultFuture();
|
||||
mockNet.runNetwork();
|
||||
assertThat(result.get()).isEqualTo("Hello");
|
||||
}
|
||||
@ -55,7 +55,7 @@ public class FlowsInJavaTest {
|
||||
}
|
||||
|
||||
private void primitiveReceiveTypeTest(Class<?> receiveType) throws InterruptedException {
|
||||
PrimitiveReceiveFlow flow = new PrimitiveReceiveFlow(CoreTestUtils.chooseIdentity(node2.getInfo()), receiveType);
|
||||
PrimitiveReceiveFlow flow = new PrimitiveReceiveFlow(chooseIdentity(node2.getInfo()), receiveType);
|
||||
Future<?> result = node1.getServices().startFlow(flow).getResultFuture();
|
||||
mockNet.runNetwork();
|
||||
try {
|
||||
|
@ -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.chooseIdentity
|
||||
import java.util.*
|
||||
|
||||
// DOCSTART CustomVaultQuery
|
||||
@ -140,7 +139,7 @@ object TopupIssuerFlow {
|
||||
val issueTx = subFlow(issueCashFlow)
|
||||
// NOTE: issueCashFlow performs a Broadcast (which stores a local copy of the txn to the ledger)
|
||||
// short-circuit when issuing to self
|
||||
if (issueTo == serviceHub.myInfo.chooseIdentity())
|
||||
if (serviceHub.myInfo.isLegalIdentity(issueTo))
|
||||
return issueTx
|
||||
// now invoke Cash subflow to Move issued assetType to issue requester
|
||||
progressTracker.currentStep = TRANSFERRING
|
||||
|
@ -47,7 +47,7 @@ private fun gatherOurInputs(serviceHub: ServiceHub,
|
||||
|
||||
val fullCriteria = fungibleCriteria.and(vaultCriteria).and(cashCriteria)
|
||||
|
||||
val eligibleStates = serviceHub.vaultService.tryLockFungibleStatesForSpending<Cash.State, Currency>(lockId, fullCriteria, amountRequired.withoutIssuer(), Cash.State::class.java)
|
||||
val eligibleStates = serviceHub.vaultService.tryLockFungibleStatesForSpending(lockId, fullCriteria, amountRequired.withoutIssuer(), Cash.State::class.java)
|
||||
|
||||
check(eligibleStates.isNotEmpty()) { "Insufficient funds" }
|
||||
val amount = eligibleStates.fold(0L) { tot, x -> tot + x.state.data.amount.quantity }
|
||||
@ -97,11 +97,11 @@ class ForeignExchangeFlow(val tradeId: String,
|
||||
// Select correct sides of the Fx exchange to query for.
|
||||
// Specifically we own the assets we wish to sell.
|
||||
// Also prepare the other side query
|
||||
val (localRequest, remoteRequest) = if (baseCurrencySeller == serviceHub.myInfo.chooseIdentity()) {
|
||||
val (localRequest, remoteRequest) = if (serviceHub.myInfo.isLegalIdentity(baseCurrencySeller)) {
|
||||
val local = FxRequest(tradeId, baseCurrencyAmount, baseCurrencySeller, baseCurrencyBuyer)
|
||||
val remote = FxRequest(tradeId, quoteCurrencyAmount, baseCurrencyBuyer, baseCurrencySeller)
|
||||
Pair(local, remote)
|
||||
} else if (baseCurrencyBuyer == serviceHub.myInfo.chooseIdentity()) {
|
||||
} else if (serviceHub.myInfo.isLegalIdentity(baseCurrencyBuyer)) {
|
||||
val local = FxRequest(tradeId, quoteCurrencyAmount, baseCurrencyBuyer, baseCurrencySeller)
|
||||
val remote = FxRequest(tradeId, baseCurrencyAmount, baseCurrencySeller, baseCurrencyBuyer)
|
||||
Pair(local, remote)
|
||||
@ -133,8 +133,8 @@ class ForeignExchangeFlow(val tradeId: String,
|
||||
>= remoteRequestWithNotary.amount.quantity) {
|
||||
"the provided inputs don't provide sufficient funds"
|
||||
}
|
||||
require(it.filter { it.owner == serviceHub.myInfo.chooseIdentity() }.
|
||||
map { it.amount.quantity }.sum() == remoteRequestWithNotary.amount.quantity) {
|
||||
val sum = it.filter { it.owner.let { it is Party && serviceHub.myInfo.isLegalIdentity(it) } }.map { it.amount.quantity }.sum()
|
||||
require(sum == remoteRequestWithNotary.amount.quantity) {
|
||||
"the provided outputs don't provide the request quantity"
|
||||
}
|
||||
it // return validated response
|
||||
@ -195,7 +195,7 @@ class ForeignExchangeFlow(val tradeId: String,
|
||||
}
|
||||
|
||||
@InitiatedBy(ForeignExchangeFlow::class)
|
||||
class ForeignExchangeRemoteFlow(val source: Party) : FlowLogic<Unit>() {
|
||||
class ForeignExchangeRemoteFlow(private val source: Party) : FlowLogic<Unit>() {
|
||||
@Suspendable
|
||||
override fun call() {
|
||||
// Initial receive from remote party
|
||||
@ -206,7 +206,7 @@ class ForeignExchangeRemoteFlow(val source: Party) : FlowLogic<Unit>() {
|
||||
// the lifecycle of the Fx trades which would be included in the transaction
|
||||
|
||||
// Check request is for us
|
||||
require(serviceHub.myInfo.chooseIdentity() == it.owner) {
|
||||
require(serviceHub.myInfo.isLegalIdentity(it.owner)) {
|
||||
"Request does not include the correct counterparty"
|
||||
}
|
||||
require(source == it.counterparty) {
|
||||
|
@ -116,7 +116,7 @@ class SubmitTradeApprovalFlow(val tradeId: String,
|
||||
// Notarise and distribute.
|
||||
subFlow(FinalityFlow(signedTx, setOf(serviceHub.myInfo.chooseIdentity(), counterparty)))
|
||||
// Return the initial state
|
||||
return signedTx.tx.outRef<TradeApprovalContract.State>(0)
|
||||
return signedTx.tx.outRef(0)
|
||||
}
|
||||
|
||||
}
|
||||
@ -149,7 +149,7 @@ class SubmitCompletionFlow(val ref: StateRef, val verdict: WorkflowState) : Flow
|
||||
"Input trade not modifiable ${latestRecord.state.data.state}"
|
||||
}
|
||||
// Check we are the correct Party to run the protocol. Note they will counter check this too.
|
||||
require(latestRecord.state.data.counterparty == serviceHub.myInfo.chooseIdentity()) {
|
||||
require(serviceHub.myInfo.isLegalIdentity(latestRecord.state.data.counterparty)) {
|
||||
"The counterparty must give the verdict"
|
||||
}
|
||||
|
||||
@ -225,7 +225,7 @@ class RecordCompletionFlow(val source: Party) : FlowLogic<Unit>() {
|
||||
// Check the context dependent parts of the transaction as the
|
||||
// Contract verify method must not use serviceHub queries.
|
||||
val state = ltx.outRef<TradeApprovalContract.State>(0)
|
||||
require(state.state.data.source == serviceHub.myInfo.chooseIdentity()) {
|
||||
require(serviceHub.myInfo.isLegalIdentity(state.state.data.source)) {
|
||||
"Proposal not one of our original proposals"
|
||||
}
|
||||
require(state.state.data.counterparty == source) {
|
||||
|
@ -99,7 +99,7 @@ class BFTNotaryServiceTests {
|
||||
val notary = bftNotaryCluster(clusterSize)
|
||||
node.run {
|
||||
val issueTx = signInitialTransaction(notary) {
|
||||
addOutputState(DummyContract.SingleOwnerState(owner = (info.chooseIdentity())), DUMMY_PROGRAM_ID)
|
||||
addOutputState(DummyContract.SingleOwnerState(owner = info.chooseIdentity()), DUMMY_PROGRAM_ID)
|
||||
}
|
||||
database.transaction {
|
||||
services.recordTransactions(issueTx)
|
||||
|
@ -579,7 +579,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
val caCertificates: Array<X509Certificate> = listOf(legalIdentity.certificate, clientCa?.certificate?.cert)
|
||||
.filterNotNull()
|
||||
.toTypedArray()
|
||||
val service = PersistentIdentityService(info.legalIdentitiesAndCerts.toSet(), trustRoot = trustRoot, caCertificates = *caCertificates)
|
||||
val service = PersistentIdentityService(info.legalIdentitiesAndCerts, trustRoot = trustRoot, caCertificates = *caCertificates)
|
||||
services.networkMapCache.partyNodes.forEach { it.legalIdentitiesAndCerts.forEach { service.verifyAndRegisterIdentity(it) } }
|
||||
services.networkMapCache.changed.subscribe { mapChange ->
|
||||
// TODO how should we handle network map removal
|
||||
|
@ -76,7 +76,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
|
||||
|
||||
override fun getPartyInfo(party: Party): PartyInfo? {
|
||||
val nodes = serviceHub.database.transaction { queryByIdentityKey(party.owningKey) }
|
||||
if (nodes.size == 1 && party in nodes[0].legalIdentities) {
|
||||
if (nodes.size == 1 && nodes[0].isLegalIdentity(party)) {
|
||||
return PartyInfo.SingleNode(party, nodes[0].addresses)
|
||||
}
|
||||
for (node in nodes) {
|
||||
|
@ -21,8 +21,8 @@ import net.corda.node.services.network.NetworkMapService
|
||||
import net.corda.node.services.statemachine.StateMachineManager
|
||||
import net.corda.node.services.transactions.ValidatingNotaryService
|
||||
import net.corda.testing.DUMMY_NOTARY
|
||||
import net.corda.testing.contracts.DUMMY_PROGRAM_ID
|
||||
import net.corda.testing.chooseIdentity
|
||||
import net.corda.testing.contracts.DUMMY_PROGRAM_ID
|
||||
import net.corda.testing.dummyCommand
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import org.junit.After
|
||||
@ -81,7 +81,7 @@ class ScheduledFlowTests {
|
||||
val state = serviceHub.toStateAndRef<ScheduledState>(stateRef)
|
||||
val scheduledState = state.state.data
|
||||
// Only run flow over states originating on this node
|
||||
if (scheduledState.source != serviceHub.myInfo.chooseIdentity()) {
|
||||
if (!serviceHub.myInfo.isLegalIdentity(scheduledState.source)) {
|
||||
return
|
||||
}
|
||||
require(!scheduledState.processed) { "State should not have been previously processed" }
|
||||
@ -144,7 +144,7 @@ class ScheduledFlowTests {
|
||||
fun `run a whole batch of scheduled flows`() {
|
||||
val N = 100
|
||||
val futures = mutableListOf<CordaFuture<*>>()
|
||||
for (i in 0..N - 1) {
|
||||
for (i in 0 until N) {
|
||||
futures.add(nodeA.services.startFlow(InsertInitialStateFlow(nodeB.info.chooseIdentity())).resultFuture)
|
||||
futures.add(nodeB.services.startFlow(InsertInitialStateFlow(nodeA.info.chooseIdentity())).resultFuture)
|
||||
}
|
||||
|
@ -10,17 +10,14 @@ import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.utilities.*
|
||||
import net.corda.node.internal.Node
|
||||
import net.corda.node.internal.StartedNode
|
||||
import net.corda.testing.ALICE
|
||||
import net.corda.testing.BOB
|
||||
import net.corda.testing.CHARLIE
|
||||
import net.corda.testing.DUMMY_NOTARY
|
||||
import net.corda.testing.chooseIdentity
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.node.NodeBasedTest
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFails
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class PersistentNetworkMapCacheTest : NodeBasedTest() {
|
||||
val partiesList = listOf(DUMMY_NOTARY, ALICE, BOB)
|
||||
@ -64,7 +61,7 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() {
|
||||
fun `restart node with DB map cache and no network map`() {
|
||||
val alice = startNodesWithPort(listOf(ALICE), noNetworkMap = true)[0]
|
||||
val partyNodes = alice.services.networkMapCache.partyNodes
|
||||
assert(NetworkMapService.type !in alice.info.advertisedServices.map { it.info.type })
|
||||
assertTrue(NetworkMapService.type !in alice.info.advertisedServices.map { it.info.type })
|
||||
assertEquals(NullNetworkMapService, alice.inNodeNetworkMapService)
|
||||
assertEquals(infos.size, partyNodes.size)
|
||||
assertEquals(infos.flatMap { it.legalIdentities }.toSet(), partyNodes.flatMap { it.legalIdentities }.toSet())
|
||||
@ -74,8 +71,8 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() {
|
||||
fun `start 2 nodes without pointing at NetworkMapService and communicate with each other`() {
|
||||
val parties = partiesList.subList(1, partiesList.size)
|
||||
val nodes = startNodesWithPort(parties, noNetworkMap = true)
|
||||
assert(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService })
|
||||
assert(nodes.all { NetworkMapService.type !in it.info.advertisedServices.map { it.info.type } })
|
||||
assertTrue(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService })
|
||||
assertTrue(nodes.all { NetworkMapService.type !in it.info.advertisedServices.map { it.info.type } })
|
||||
nodes.forEach {
|
||||
val partyNodes = it.services.networkMapCache.partyNodes
|
||||
assertEquals(infos.size, partyNodes.size)
|
||||
@ -88,8 +85,8 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() {
|
||||
fun `start 2 nodes pointing at NetworkMapService but don't start network map node`() {
|
||||
val parties = partiesList.subList(1, partiesList.size)
|
||||
val nodes = startNodesWithPort(parties, noNetworkMap = false)
|
||||
assert(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService })
|
||||
assert(nodes.all { NetworkMapService.type !in it.info.advertisedServices.map { it.info.type } })
|
||||
assertTrue(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService })
|
||||
assertTrue(nodes.all { NetworkMapService.type !in it.info.advertisedServices.map { it.info.type } })
|
||||
nodes.forEach {
|
||||
val partyNodes = it.services.networkMapCache.partyNodes
|
||||
assertEquals(infos.size, partyNodes.size)
|
||||
@ -116,20 +113,20 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() {
|
||||
// Start 2 nodes pointing at network map, but don't start network map service.
|
||||
val otherNodes = startNodesWithPort(parties, noNetworkMap = false)
|
||||
otherNodes.forEach { node ->
|
||||
assert(infos.any { it.legalIdentitiesAndCerts.toSet() == node.info.legalIdentitiesAndCerts.toSet() })
|
||||
assertTrue(infos.any { it.legalIdentitiesAndCerts.toSet() == node.info.legalIdentitiesAndCerts.toSet() })
|
||||
}
|
||||
// Start node that is not in databases of other nodes. Point to NMS. Which has't started yet.
|
||||
val charlie = startNodesWithPort(listOf(CHARLIE), noNetworkMap = false)[0]
|
||||
otherNodes.forEach {
|
||||
assert(charlie.info.chooseIdentity() !in it.services.networkMapCache.partyNodes.flatMap { it.legalIdentities })
|
||||
assertThat(it.services.networkMapCache.partyNodes).doesNotContain(charlie.info)
|
||||
}
|
||||
// Start Network Map and see that charlie node appears in caches.
|
||||
val nms = startNodesWithPort(listOf(DUMMY_NOTARY), noNetworkMap = false)[0]
|
||||
nms.internals.startupComplete.get()
|
||||
assert(nms.inNodeNetworkMapService != NullNetworkMapService)
|
||||
assert(infos.any { it.legalIdentities.toSet() == nms.info.legalIdentities.toSet() })
|
||||
assertTrue(nms.inNodeNetworkMapService != NullNetworkMapService)
|
||||
assertTrue(infos.any { it.legalIdentities.toSet() == nms.info.legalIdentities.toSet() })
|
||||
otherNodes.forEach {
|
||||
assert(nms.info.chooseIdentity() in it.services.networkMapCache.partyNodes.map { it.chooseIdentity() })
|
||||
assertTrue(nms.info.chooseIdentity() in it.services.networkMapCache.partyNodes.map { it.chooseIdentity() })
|
||||
}
|
||||
charlie.internals.nodeReadyFuture.get() // Finish registration.
|
||||
checkConnectivity(listOf(otherNodes[0], nms)) // Checks connectivity from A to NMS.
|
||||
@ -137,7 +134,7 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() {
|
||||
val cacheB = otherNodes[1].services.networkMapCache.partyNodes
|
||||
val cacheC = charlie.services.networkMapCache.partyNodes
|
||||
assertEquals(4, cacheC.size) // Charlie fetched data from NetworkMap
|
||||
assert(charlie.info.chooseIdentity() in cacheB.map { it.chooseIdentity() }) // Other nodes also fetched data from Network Map with node C.
|
||||
assertThat(cacheB).contains(charlie.info)
|
||||
assertEquals(cacheA.toSet(), cacheB.toSet())
|
||||
assertEquals(cacheA.toSet(), cacheC.toSet())
|
||||
}
|
||||
|
@ -28,8 +28,10 @@ import net.corda.client.jfx.model.*
|
||||
import net.corda.client.jfx.utils.*
|
||||
import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.CityDatabase
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.node.ScreenCoordinate
|
||||
import net.corda.core.node.WorldMapLocation
|
||||
import net.corda.core.utilities.toBase58String
|
||||
import net.corda.explorer.formatters.PartyNameFormatter
|
||||
import net.corda.explorer.model.CordaView
|
||||
@ -39,10 +41,10 @@ class Network : CordaView() {
|
||||
override val root by fxml<Parent>()
|
||||
override val icon = FontAwesomeIcon.GLOBE
|
||||
// Inject data.
|
||||
val myIdentity by observableValue(NetworkIdentityModel::myIdentity)
|
||||
val notaries by observableList(NetworkIdentityModel::notaries)
|
||||
val peers by observableList(NetworkIdentityModel::parties)
|
||||
val transactions by observableList(TransactionDataModel::partiallyResolvedTransactions)
|
||||
private val myIdentity by observableValue(NetworkIdentityModel::myIdentity)
|
||||
private val notaries by observableList(NetworkIdentityModel::notaries)
|
||||
private val peers by observableList(NetworkIdentityModel::parties)
|
||||
private val transactions by observableList(TransactionDataModel::partiallyResolvedTransactions)
|
||||
var centralPeer: String? = null
|
||||
private var centralLabel: ObservableValue<Label?>
|
||||
|
||||
@ -215,8 +217,8 @@ class Network : CordaView() {
|
||||
private fun List<ContractState>.getParties() = map { it.participants.map { it.owningKey.toKnownParty() } }.flatten()
|
||||
|
||||
private fun fireBulletBetweenNodes(senderParty: Party, destParty: Party, startType: String, endType: String) {
|
||||
val senderNode = allComponents.firstOrNull { senderParty in it.nodeInfo.legalIdentities } ?: return
|
||||
val destNode = allComponents.firstOrNull { destParty in it.nodeInfo.legalIdentities } ?: return
|
||||
val senderNode = allComponents.firstOrNull { it.nodeInfo.isLegalIdentity(senderParty) } ?: return
|
||||
val destNode = allComponents.firstOrNull { it.nodeInfo.isLegalIdentity(destParty) } ?: return
|
||||
val sender = senderNode.label.boundsInParentProperty().map { Point2D(it.width / 2 + it.minX, it.height / 4 - 2.5 + it.minY) }
|
||||
val receiver = destNode.label.boundsInParentProperty().map { Point2D(it.width / 2 + it.minX, it.height / 4 - 2.5 + it.minY) }
|
||||
val bullet = Circle(3.0)
|
||||
@ -254,4 +256,8 @@ class Network : CordaView() {
|
||||
mapPane.children.add(1, line)
|
||||
mapPane.children.add(bullet)
|
||||
}
|
||||
|
||||
private fun NodeInfo.getWorldMapLocation(): WorldMapLocation? {
|
||||
return CityDatabase[legalIdentitiesAndCerts[0].name.locality]
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user