diff --git a/core/src/main/kotlin/core/node/services/IdentityService.kt b/core/src/main/kotlin/core/node/services/IdentityService.kt index e89f3ca80b..c2006c32fd 100644 --- a/core/src/main/kotlin/core/node/services/IdentityService.kt +++ b/core/src/main/kotlin/core/node/services/IdentityService.kt @@ -9,6 +9,8 @@ import java.security.PublicKey * service would provide. */ interface IdentityService { + fun registerIdentity(party: Party) + fun deregisterIdentity(party: Party) fun partyFromKey(key: PublicKey): Party? fun partyFromName(name: String): Party? } diff --git a/src/main/kotlin/core/node/AbstractNode.kt b/src/main/kotlin/core/node/AbstractNode.kt index d57d69f223..d7ff3a2dba 100644 --- a/src/main/kotlin/core/node/AbstractNode.kt +++ b/src/main/kotlin/core/node/AbstractNode.kt @@ -121,24 +121,14 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, // know about: our own, the identity of the remote timestamper node (if any), plus whatever is in the // network map. // - // TODO: All this will be replaced soon enough. - val fixedIdentities = if (timestamperAddress != null) - listOf(storage.myLegalIdentity, timestamperAddress.identity) - else - listOf(storage.myLegalIdentity) + val service = InMemoryIdentityService() + if (timestamperAddress != null) + service.registerIdentity(timestamperAddress.identity) + service.registerIdentity(storage.myLegalIdentity) - return object : IdentityService { - private val identities: List<Party> get() = fixedIdentities + services.networkMapCache.partyNodes.map { it.identity } - private val keyToParties: Map<PublicKey, Party> get() = identities.associateBy { it.owningKey } - private val nameToParties: Map<String, Party> get() = identities.associateBy { it.name } + services.networkMapCache.partyNodes.forEach { service.registerIdentity(it.identity) } - override fun partyFromKey(key: PublicKey): Party? = keyToParties[key] - override fun partyFromName(name: String): Party? = nameToParties[name] - - override fun toString(): String { - return identities.joinToString { it.name } - } - } + return service } open fun stop() { diff --git a/src/main/kotlin/core/node/services/InMemoryIdentityService.kt b/src/main/kotlin/core/node/services/InMemoryIdentityService.kt new file mode 100644 index 0000000000..2e2a1260e4 --- /dev/null +++ b/src/main/kotlin/core/node/services/InMemoryIdentityService.kt @@ -0,0 +1,26 @@ +package core.node.services + +import core.Party +import java.security.PublicKey +import java.util.concurrent.ConcurrentHashMap +import javax.annotation.concurrent.ThreadSafe + +/** + * Simple identity service which caches parties and provides functionality for efficient lookup. + */ +@ThreadSafe +class InMemoryIdentityService() : IdentityService { + private val keyToParties = ConcurrentHashMap<PublicKey, Party>() + private val nameToParties = ConcurrentHashMap<String, Party>() + + override fun registerIdentity(party: Party) { + keyToParties[party.owningKey] = party + nameToParties[party.name] = party + } + override fun deregisterIdentity(party: Party) { + keyToParties.remove(party.owningKey) + nameToParties.remove(party.name) + } + override fun partyFromKey(key: PublicKey): Party? = keyToParties[key] + override fun partyFromName(name: String): Party? = nameToParties[name] +} \ No newline at end of file diff --git a/src/main/kotlin/core/testing/IRSSimulation.kt b/src/main/kotlin/core/testing/IRSSimulation.kt index e345b5ac5d..bba97c5ff7 100644 --- a/src/main/kotlin/core/testing/IRSSimulation.kt +++ b/src/main/kotlin/core/testing/IRSSimulation.kt @@ -7,7 +7,7 @@ import com.google.common.util.concurrent.SettableFuture import contracts.InterestRateSwap import core.* import core.crypto.SecureHash -import core.node.services.FixedIdentityService +import core.testing.MockIdentityService import core.node.services.linearHeadsOfType import core.utilities.JsonSupport import protocols.TwoPartyDealProtocol @@ -19,7 +19,7 @@ import java.util.* * A simulation in which banks execute interest rate swaps with each other, including the fixing events. */ class IRSSimulation(runAsync: Boolean, latencyInjector: InMemoryMessagingNetwork.LatencyCalculator?) : Simulation(runAsync, latencyInjector) { - val om = JsonSupport.createDefaultMapper(FixedIdentityService(network.identities)) + val om = JsonSupport.createDefaultMapper(MockIdentityService(network.identities)) init { currentDay = LocalDate.of(2016, 3, 10) // Should be 12th but the actual first fixing date gets rolled backwards. diff --git a/src/main/kotlin/core/node/services/FixedIdentityService.kt b/src/main/kotlin/core/testing/MockIdentityService.kt similarity index 73% rename from src/main/kotlin/core/node/services/FixedIdentityService.kt rename to src/main/kotlin/core/testing/MockIdentityService.kt index 970d49459b..7772238ae4 100644 --- a/src/main/kotlin/core/node/services/FixedIdentityService.kt +++ b/src/main/kotlin/core/testing/MockIdentityService.kt @@ -1,6 +1,7 @@ -package core.node.services +package core.testing import core.Party +import core.node.services.IdentityService import java.security.PublicKey import javax.annotation.concurrent.ThreadSafe @@ -11,12 +12,14 @@ import javax.annotation.concurrent.ThreadSafe * MockNetwork code. */ @ThreadSafe -class FixedIdentityService(val identities: List<Party>) : IdentityService { +class MockIdentityService(val identities: List<Party>) : IdentityService { private val keyToParties: Map<PublicKey, Party> get() = synchronized(identities) { identities.associateBy { it.owningKey } } private val nameToParties: Map<String, Party> get() = synchronized(identities) { identities.associateBy { it.name } } + override fun registerIdentity(party: Party) { throw UnsupportedOperationException() } + override fun deregisterIdentity(party: Party) { throw UnsupportedOperationException() } override fun partyFromKey(key: PublicKey): Party? = keyToParties[key] override fun partyFromName(name: String): Party? = nameToParties[name] } \ No newline at end of file diff --git a/src/main/kotlin/core/testing/MockNode.kt b/src/main/kotlin/core/testing/MockNode.kt index cb80723923..548d0410fb 100644 --- a/src/main/kotlin/core/testing/MockNode.kt +++ b/src/main/kotlin/core/testing/MockNode.kt @@ -9,7 +9,7 @@ import core.node.AbstractNode import core.node.NodeConfiguration import core.node.NodeInfo import core.node.PhysicalLocation -import core.node.services.FixedIdentityService +import core.testing.MockIdentityService import core.node.services.ServiceType import core.node.services.TimestamperService import core.utilities.loggerFor @@ -75,7 +75,7 @@ class MockNetwork(private val threadPerNode: Boolean = false, return mockNet.messagingNetwork.createNodeWithID(!mockNet.threadPerNode, id).start().get() } - override fun makeIdentityService() = FixedIdentityService(mockNet.identities) + override fun makeIdentityService() = MockIdentityService(mockNet.identities) // There is no need to slow down the unit tests by initialising CityDatabase override fun findMyLocation(): PhysicalLocation? = null diff --git a/src/main/kotlin/demos/IRSDemo.kt b/src/main/kotlin/demos/IRSDemo.kt index d4d235fb67..1ff7339bbe 100644 --- a/src/main/kotlin/demos/IRSDemo.kt +++ b/src/main/kotlin/demos/IRSDemo.kt @@ -108,6 +108,7 @@ fun main(args: Array<String>) { try { val peerId = nodeInfo(hostAndPortString, identityFile) (node.services.networkMapCache as MockNetworkMapCache).partyNodes.add(peerId) + node.services.identityService.registerIdentity(peerId.identity) } catch (e: Exception) { } } diff --git a/src/test/kotlin/core/testutils/TestUtils.kt b/src/test/kotlin/core/testutils/TestUtils.kt index 2ec2e02af7..6d71d0e2af 100644 --- a/src/test/kotlin/core/testutils/TestUtils.kt +++ b/src/test/kotlin/core/testutils/TestUtils.kt @@ -7,7 +7,7 @@ import contracts.* import core.* import core.crypto.* import core.node.services.DummyTimestampingAuthority -import core.node.services.FixedIdentityService +import core.testing.MockIdentityService import core.serialization.serialize import core.visualiser.GraphVisualiser import java.security.KeyPair @@ -60,7 +60,7 @@ val MINI_CORP = Party("MiniCorp", MINI_CORP_PUBKEY) val ALL_TEST_KEYS = listOf(MEGA_CORP_KEY, MINI_CORP_KEY, ALICE_KEY, BOB_KEY, DummyTimestampingAuthority.key) -val MockIdentityService = FixedIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_TIMESTAMPER.identity)) +val MockIdentityService = MockIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_TIMESTAMPER.identity)) // In a real system this would be a persistent map of hash to bytecode and we'd instantiate the object as needed inside // a sandbox. For unit tests we just have a hard-coded list.