diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/PublicKeyToOwningIdentityCache.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/PublicKeyToOwningIdentityCache.kt index e7f0e3ec3c..4c66b14396 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/PublicKeyToOwningIdentityCache.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/PublicKeyToOwningIdentityCache.kt @@ -11,7 +11,7 @@ interface PublicKeyToOwningIdentityCache { /** * Obtain the owning identity for a public key. * - * If the key is unknown to the node, then this will return null. + * If the key is unknown to the node, then this will return [KeyOwningIdentity.UnmappedIdentity]. */ - operator fun get(key: PublicKey): KeyOwningIdentity? + operator fun get(key: PublicKey): KeyOwningIdentity } \ No newline at end of file diff --git a/node/src/main/kotlin/net/corda/node/services/identity/PersistentIdentityService.kt b/node/src/main/kotlin/net/corda/node/services/identity/PersistentIdentityService.kt index 6e896a6d22..ac91bdec68 100644 --- a/node/src/main/kotlin/net/corda/node/services/identity/PersistentIdentityService.kt +++ b/node/src/main/kotlin/net/corda/node/services/identity/PersistentIdentityService.kt @@ -413,6 +413,9 @@ class PersistentIdentityService(cacheFactory: NamedCacheFactory) : SingletonSeri return database.transaction { log.info("Linking: ${publicKey.hash} to ${party.name}") keyToName[publicKey.toStringShort()] = party.name + if (party == wellKnownPartyFromX500Name(ourNames.first())) { + _pkToIdCache[publicKey] = KeyOwningIdentity.UnmappedIdentity + } } } @@ -422,7 +425,7 @@ class PersistentIdentityService(cacheFactory: NamedCacheFactory) : SingletonSeri } override fun externalIdForPublicKey(publicKey: PublicKey): UUID? { - return _pkToIdCache[publicKey]?.uuid + return _pkToIdCache[publicKey].uuid } private fun publicKeysForExternalId(externalId: UUID, table: Class<*>): List { diff --git a/node/src/main/kotlin/net/corda/node/services/persistence/PublicKeyToOwningIdentityCacheImpl.kt b/node/src/main/kotlin/net/corda/node/services/persistence/PublicKeyToOwningIdentityCacheImpl.kt index 7dcae65237..fd3d01431d 100644 --- a/node/src/main/kotlin/net/corda/node/services/persistence/PublicKeyToOwningIdentityCacheImpl.kt +++ b/node/src/main/kotlin/net/corda/node/services/persistence/PublicKeyToOwningIdentityCacheImpl.kt @@ -5,12 +5,9 @@ import net.corda.core.crypto.toStringShort import net.corda.core.internal.NamedCacheFactory import net.corda.core.utilities.contextLogger import net.corda.core.utilities.debug -import net.corda.node.services.identity.PersistentIdentityService -import net.corda.node.services.keys.BasicHSMKeyManagementService import net.corda.nodeapi.internal.KeyOwningIdentity import net.corda.nodeapi.internal.persistence.CordaPersistence import java.security.PublicKey -import java.util.* /** * The [PublicKeyToOwningIdentityCacheImpl] provides a caching layer over the pk_hash_to_external_id table. Gets will attempt to read an @@ -22,42 +19,10 @@ class PublicKeyToOwningIdentityCacheImpl(private val database: CordaPersistence, val log = contextLogger() } - private val cache = cacheFactory.buildNamed(Caffeine.newBuilder(), "PublicKeyToOwningIdentityCache_cache") - - /** - * Establish whether a public key is one of the node's identity keys, by looking in the node's identity database table. - */ - private fun isKeyIdentityKey(key: PublicKey): Boolean { - return database.transaction { - val criteriaBuilder = session.criteriaBuilder - val criteriaQuery = criteriaBuilder.createQuery(Long::class.java) - val queryRoot = criteriaQuery.from(PersistentIdentityService.PersistentPublicKeyHashToCertificate::class.java) - criteriaQuery.select(criteriaBuilder.count(queryRoot)) - criteriaQuery.where( - criteriaBuilder.equal(queryRoot.get(PersistentIdentityService.PersistentPublicKeyHashToCertificate::publicKeyHash.name), key.toStringShort()) - ) - val query = session.createQuery(criteriaQuery) - query.uniqueResult() > 0 - } - } - - /** - * Check to see if the key belongs to one of the key pairs in the node_our_key_pairs table. These keys may relate to confidential - * identities. - */ - private fun isKeyPartOfNodeKeyPairs(key: PublicKey): Boolean { - return database.transaction { - val criteriaBuilder = session.criteriaBuilder - val criteriaQuery = criteriaBuilder.createQuery(Long::class.java) - val queryRoot = criteriaQuery.from(BasicHSMKeyManagementService.PersistentKey::class.java) - criteriaQuery.select(criteriaBuilder.count(queryRoot)) - criteriaQuery.where( - criteriaBuilder.equal(queryRoot.get(BasicHSMKeyManagementService.PersistentKey::publicKeyHash.name), key.toStringShort()) - ) - val query = session.createQuery(criteriaQuery) - query.uniqueResult() > 0 - } - } + private val cache = cacheFactory.buildNamed( + Caffeine.newBuilder(), + "PublicKeyToOwningIdentityCache_cache" + ) /** * Return the owning identity associated with a given key. @@ -65,25 +30,17 @@ class PublicKeyToOwningIdentityCacheImpl(private val database: CordaPersistence, * This method caches the result of a database lookup to prevent multiple database accesses for the same key. This assumes that once a * key is generated, the UUID assigned to it is never changed. */ - override operator fun get(key: PublicKey): KeyOwningIdentity? { + override operator fun get(key: PublicKey): KeyOwningIdentity { return cache.asMap().computeIfAbsent(key) { database.transaction { - val criteriaBuilder = session.criteriaBuilder - val criteriaQuery = criteriaBuilder.createQuery(UUID::class.java) - val queryRoot = criteriaQuery.from(PublicKeyHashToExternalId::class.java) - criteriaQuery.select(queryRoot.get(PublicKeyHashToExternalId::externalId.name)) - criteriaQuery.where( - criteriaBuilder.equal(queryRoot.get(PublicKeyHashToExternalId::publicKeyHash.name), key.toStringShort()) - ) - val query = session.createQuery(criteriaQuery) - val uuid = query.uniqueResult() - if (uuid != null || isKeyPartOfNodeKeyPairs(key) || isKeyIdentityKey(key)) { + val uuid = session.find(PublicKeyHashToExternalId::class.java, key.toStringShort())?.externalId + if (uuid != null) { val signingEntity = KeyOwningIdentity.fromUUID(uuid) log.debug { "Database lookup for public key ${key.toStringShort()}, found signing entity $signingEntity" } signingEntity } else { - log.debug { "Attempted to find owning identity for public key ${key.toStringShort()}, but key is unknown to node" } - null + log.debug { "Database lookup for public key ${key.toStringShort()}, using ${KeyOwningIdentity.UnmappedIdentity}" } + KeyOwningIdentity.UnmappedIdentity } } } diff --git a/node/src/test/kotlin/net/corda/node/services/persistence/PublicKeyToOwningIdentityCacheImplTest.kt b/node/src/test/kotlin/net/corda/node/services/persistence/PublicKeyToOwningIdentityCacheImplTest.kt index af31369209..5f71169ef4 100644 --- a/node/src/test/kotlin/net/corda/node/services/persistence/PublicKeyToOwningIdentityCacheImplTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/persistence/PublicKeyToOwningIdentityCacheImplTest.kt @@ -114,9 +114,9 @@ class PublicKeyToOwningIdentityCacheImplTest { } @Test(timeout=300_000) - fun `requesting a key unknown to the node returns null`() { + fun `requesting a key unknown to the node returns unmapped identity`() { val keys = generateKeyPair() - assertEquals(null, testCache[keys.public]) + assertEquals(KeyOwningIdentity.UnmappedIdentity, testCache[keys.public]) } @Test(timeout=300_000) diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/MockPublicKeyToOwningIdentityCache.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/MockPublicKeyToOwningIdentityCache.kt index c8acf07faf..06abf4a1cc 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/MockPublicKeyToOwningIdentityCache.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/MockPublicKeyToOwningIdentityCache.kt @@ -13,8 +13,8 @@ class MockPublicKeyToOwningIdentityCache : WritablePublicKeyToOwningIdentityCach private val cache: MutableMap = mutableMapOf().toSynchronised() - override fun get(key: PublicKey): KeyOwningIdentity? { - return cache[key] + override fun get(key: PublicKey): KeyOwningIdentity { + return cache[key] ?: KeyOwningIdentity.UnmappedIdentity } override fun set(key: PublicKey, value: KeyOwningIdentity) {