mirror of
https://github.com/corda/corda.git
synced 2024-12-21 13:57:54 +00:00
CORDA-3818: Synchronize OS implementation of PublicKeyToOwningIdentityCache with CE
This commit is contained in:
parent
330a95cb68
commit
5afdb63c94
@ -11,7 +11,7 @@ interface PublicKeyToOwningIdentityCache {
|
|||||||
/**
|
/**
|
||||||
* Obtain the owning identity for a public key.
|
* 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 {
|
return database.transaction {
|
||||||
log.info("Linking: ${publicKey.hash} to ${party.name}")
|
log.info("Linking: ${publicKey.hash} to ${party.name}")
|
||||||
keyToName[publicKey.toStringShort()] = 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? {
|
override fun externalIdForPublicKey(publicKey: PublicKey): UUID? {
|
||||||
return _pkToIdCache[publicKey]?.uuid
|
return _pkToIdCache[publicKey].uuid
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun publicKeysForExternalId(externalId: UUID, table: Class<*>): List<PublicKey> {
|
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.internal.NamedCacheFactory
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.core.utilities.debug
|
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.KeyOwningIdentity
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import java.security.PublicKey
|
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
|
* 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()
|
val log = contextLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val cache = cacheFactory.buildNamed<PublicKey, KeyOwningIdentity>(Caffeine.newBuilder(), "PublicKeyToOwningIdentityCache_cache")
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the owning identity associated with a given key.
|
* 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
|
* 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.
|
* 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) {
|
return cache.asMap().computeIfAbsent(key) {
|
||||||
database.transaction {
|
database.transaction {
|
||||||
val criteriaBuilder = session.criteriaBuilder
|
val uuid = session.find(PublicKeyHashToExternalId::class.java, key.toStringShort())?.externalId
|
||||||
val criteriaQuery = criteriaBuilder.createQuery(UUID::class.java)
|
if (uuid != null) {
|
||||||
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 signingEntity = KeyOwningIdentity.fromUUID(uuid)
|
val signingEntity = KeyOwningIdentity.fromUUID(uuid)
|
||||||
log.debug { "Database lookup for public key ${key.toStringShort()}, found signing entity $signingEntity" }
|
log.debug { "Database lookup for public key ${key.toStringShort()}, found signing entity $signingEntity" }
|
||||||
signingEntity
|
signingEntity
|
||||||
} else {
|
} else {
|
||||||
log.debug { "Attempted to find owning identity for public key ${key.toStringShort()}, but key is unknown to node" }
|
log.debug { "Database lookup for public key ${key.toStringShort()}, using ${KeyOwningIdentity.UnmappedIdentity}" }
|
||||||
null
|
KeyOwningIdentity.UnmappedIdentity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,9 +114,9 @@ class PublicKeyToOwningIdentityCacheImplTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=300_000)
|
@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()
|
val keys = generateKeyPair()
|
||||||
assertEquals(null, testCache[keys.public])
|
assertEquals(KeyOwningIdentity.UnmappedIdentity, testCache[keys.public])
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
|
@ -13,8 +13,8 @@ class MockPublicKeyToOwningIdentityCache : WritablePublicKeyToOwningIdentityCach
|
|||||||
|
|
||||||
private val cache: MutableMap<PublicKey, KeyOwningIdentity> = mutableMapOf<PublicKey, KeyOwningIdentity>().toSynchronised()
|
private val cache: MutableMap<PublicKey, KeyOwningIdentity> = mutableMapOf<PublicKey, KeyOwningIdentity>().toSynchronised()
|
||||||
|
|
||||||
override fun get(key: PublicKey): KeyOwningIdentity? {
|
override fun get(key: PublicKey): KeyOwningIdentity {
|
||||||
return cache[key]
|
return cache[key] ?: KeyOwningIdentity.UnmappedIdentity
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun set(key: PublicKey, value: KeyOwningIdentity) {
|
override fun set(key: PublicKey, value: KeyOwningIdentity) {
|
||||||
|
Loading…
Reference in New Issue
Block a user