mirror of
https://github.com/corda/corda.git
synced 2024-12-19 04:57:58 +00:00
Merge pull request #6285 from corda/denis/CORDA-3818-sync-identity-service
CORDA-3818: Synchronize OS implementation of PublicKeyToOwningIdentityCache with CE
This commit is contained in:
commit
499c09e77b
@ -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
|
||||
}
|
@ -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<PublicKey> {
|
||||
|
@ -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<PublicKey, KeyOwningIdentity>(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<String>(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<String>(BasicHSMKeyManagementService.PersistentKey::publicKeyHash.name), key.toStringShort())
|
||||
)
|
||||
val query = session.createQuery(criteriaQuery)
|
||||
query.uniqueResult() > 0
|
||||
}
|
||||
}
|
||||
private val cache = cacheFactory.buildNamed<PublicKey, KeyOwningIdentity>(
|
||||
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<String>(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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -13,8 +13,8 @@ class MockPublicKeyToOwningIdentityCache : WritablePublicKeyToOwningIdentityCach
|
||||
|
||||
private val cache: MutableMap<PublicKey, KeyOwningIdentity> = mutableMapOf<PublicKey, KeyOwningIdentity>().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) {
|
||||
|
Loading…
Reference in New Issue
Block a user