From 9b15d4dafbb1ac75c10fd6e2227219a93899066d Mon Sep 17 00:00:00 2001 From: Roger Willis Date: Thu, 22 Nov 2018 14:31:34 +0000 Subject: [PATCH] CORDA-2232: external id to pubkey mapping (#4210) * First pass Update test. Address review comments. Added docs and kdocs. Clean-up. * Addressed review comments. Changes to docsite. * First pass at account service. Added new hibernate schemas and liquibase scripts. Added indexes to new tables. Removed mock network. Removed fresh key for external id from key management service. Removed some redundant changes. Rebase to master. * Clean up. * Added try/catch block as recommended by Andras. * Removed accounts test to another branch. Removed element collections from fungible states and linear states table. Added a new state_parties table which stores x500 names and public key hashes. Added a view which can be used to query by external ID. * Removed try catch block. It's not required as the checkpoint serialiser deals with this. Re-used existing DB session instead of creating a new session. Entity manager auto flushes. * Added java friendly api. *  This is a combination of 10 commits.  This is the 1st commit message: Shortened table name.  This is the commit message #2: Minor changes.  This is the commit message #3: Common criteria parser now returns a predicate set which is concatenated to the predicate sets of sub-class criteria.  This is the commit message #4: Fixed api compatibility issue. Reverted some changes to reduce size of PR.  This is the commit message #5: Multiple states can now be mapped to the same externalId. Multiple externalIds can now be mapped to the same state.  This is the commit message #6: Relaxed upper bound type constraint in some of the vault types.  This is the commit message #7: Added comment to test.  This is the commit message #8: Changed name of external id to public key join table. Removed some comments/TODOs.  This is the commit message #9: Added docs. General clean up.  This is the commit message #10: Fixed participants query bug and updated unit test. * Removed unused code. --- .ci/api-current.txt | 12 +- .../core/node/services/vault/QueryCriteria.kt | 16 ++- .../node/services/vault/QueryCriteriaUtils.kt | 3 +- docs/source/api-persistence.rst | 6 +- docs/source/api-vault-query.rst | 80 +++++++++++ .../source/resources/state-to-external-id.png | Bin 0 -> 100647 bytes .../keys/PersistentKeyManagementService.kt | 26 +++- .../node/services/schema/NodeSchemaService.kt | 16 +-- .../vault/HibernateQueryCriteriaParser.kt | 49 +++++-- .../node/services/vault/NodeVaultService.kt | 9 +- .../corda/node/services/vault/VaultSchema.kt | 96 ++++++++----- .../vault-schema.changelog-master.xml | 1 + .../migration/vault-schema.changelog-v8.xml | 36 +++++ .../services/vault/ExternalIdMappingTest.kt | 131 ++++++++++++++++++ 14 files changed, 401 insertions(+), 80 deletions(-) create mode 100644 docs/source/resources/state-to-external-id.png create mode 100644 node/src/main/resources/migration/vault-schema.changelog-v8.xml create mode 100644 node/src/test/kotlin/net/corda/node/services/vault/ExternalIdMappingTest.kt diff --git a/.ci/api-current.txt b/.ci/api-current.txt index 0028c8444c..58d8d92ba5 100644 --- a/.ci/api-current.txt +++ b/.ci/api-current.txt @@ -4041,7 +4041,7 @@ public static final class net.corda.core.node.services.vault.QueryCriteria$Fungi @Nullable public final java.util.List getOwner() @Nullable - public final java.util.List getParticipants() + public java.util.List getParticipants() @Nullable public final net.corda.core.node.services.vault.ColumnPredicate getQuantity() @NotNull @@ -4078,7 +4078,7 @@ public static final class net.corda.core.node.services.vault.QueryCriteria$Linea @Nullable public final java.util.List getExternalId() @Nullable - public final java.util.List getParticipants() + public java.util.List getParticipants() @NotNull public net.corda.core.node.services.Vault$StateStatus getStatus() @Nullable @@ -4305,16 +4305,16 @@ public abstract class net.corda.core.node.services.vault.SortAttribute extends j ## @CordaSerializable public static final class net.corda.core.node.services.vault.SortAttribute$Custom extends net.corda.core.node.services.vault.SortAttribute - public (Class, String) + public (Class, String) @NotNull - public final Class component1() + public final Class component1() @NotNull public final String component2() @NotNull - public final net.corda.core.node.services.vault.SortAttribute$Custom copy(Class, String) + public final net.corda.core.node.services.vault.SortAttribute$Custom copy(Class, String) public boolean equals(Object) @NotNull - public final Class getEntityStateClass() + public final Class getEntityStateClass() @NotNull public final String getEntityStateColumnName() public int hashCode() diff --git a/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteria.kt b/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteria.kt index 553320c7fa..d85bc7b3f4 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteria.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteria.kt @@ -8,7 +8,7 @@ import net.corda.core.contracts.StateRef import net.corda.core.contracts.UniqueIdentifier import net.corda.core.identity.AbstractParty import net.corda.core.node.services.Vault -import net.corda.core.schemas.PersistentState +import net.corda.core.schemas.StatePersistable import net.corda.core.serialization.CordaSerializable import net.corda.core.utilities.OpaqueBytes import java.time.Instant @@ -76,6 +76,7 @@ sealed class QueryCriteria : GenericQueryCriteria = emptySet() open val constraints: Set = emptySet() + open val participants: List? = null abstract val contractStateTypes: Set>? override fun visit(parser: IQueryCriteriaParser): Collection { return parser.parseCriteria(this) @@ -94,7 +95,8 @@ sealed class QueryCriteria : GenericQueryCriteria = emptySet(), - override val constraints: Set = emptySet() + override val constraints: Set = emptySet(), + override val participants: List? = null ) : CommonQueryCriteria() { override fun visit(parser: IQueryCriteriaParser): Collection { super.visit(parser) @@ -124,7 +126,7 @@ sealed class QueryCriteria : GenericQueryCriteria? = null, + override val participants: List? = null, val uuid: List? = null, val externalId: List? = null, override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, @@ -172,7 +174,7 @@ sealed class QueryCriteria : GenericQueryCriteria? = null, + override val participants: List? = null, val quantity: ColumnPredicate? = null, override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, override val contractStateTypes: Set>? = null, @@ -188,7 +190,7 @@ sealed class QueryCriteria : GenericQueryCriteria? = null, + override val participants: List? = null, val owner: List? = null, val quantity: ColumnPredicate? = null, val issuer: List? = null, @@ -231,7 +233,7 @@ sealed class QueryCriteria : GenericQueryCriteria @JvmOverloads constructor( + data class VaultCustomQueryCriteria @JvmOverloads constructor( val expression: CriteriaExpression, override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, override val contractStateTypes: Set>? = null, @@ -299,7 +301,7 @@ interface IQueryCriteriaParser : BaseQueryCriteriaParser fun parseCriteria(criteria: QueryCriteria.FungibleAssetQueryCriteria): Collection fun parseCriteria(criteria: QueryCriteria.LinearStateQueryCriteria): Collection - fun parseCriteria(criteria: QueryCriteria.VaultCustomQueryCriteria): Collection + fun parseCriteria(criteria: QueryCriteria.VaultCustomQueryCriteria): Collection fun parseCriteria(criteria: QueryCriteria.VaultQueryCriteria): Collection } diff --git a/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteriaUtils.kt b/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteriaUtils.kt index 2492313d0b..7bf52cffe8 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteriaUtils.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteriaUtils.kt @@ -10,6 +10,7 @@ import net.corda.core.node.services.vault.ColumnPredicate.* import net.corda.core.node.services.vault.EqualityComparisonOperator.* import net.corda.core.node.services.vault.LikenessOperator.* import net.corda.core.schemas.PersistentState +import net.corda.core.schemas.StatePersistable import net.corda.core.serialization.CordaSerializable import java.lang.reflect.Field import kotlin.jvm.internal.CallableReference @@ -234,7 +235,7 @@ sealed class SortAttribute { * [entityStateColumnName] should reference an entity attribute name as defined by the associated mapped schema * (for example, [CashSchemaV1.PersistentCashState::currency.name]) */ - data class Custom(val entityStateClass: Class, + data class Custom(val entityStateClass: Class, val entityStateColumnName: String) : SortAttribute() } diff --git a/docs/source/api-persistence.rst b/docs/source/api-persistence.rst index f1ca9ef1df..70008c75e4 100644 --- a/docs/source/api-persistence.rst +++ b/docs/source/api-persistence.rst @@ -164,7 +164,7 @@ useful if off-ledger data must be maintained in conjunction with on-ledger state as a custom schema. See Samples below. The code snippet below defines a ``PersistentFoo`` type inside ``FooSchemaV1``. Note that ``PersistentFoo`` is added to -a list of mapped types which is passed to ``MappedSChema``. This is exactly how state schemas are defined, except that +a list of mapped types which is passed to ``MappedSchema``. This is exactly how state schemas are defined, except that the entity in this case should not subclass ``PersistentState`` (as it is not a state object). See examples: .. container:: codeset @@ -173,7 +173,6 @@ the entity in this case should not subclass ``PersistentState`` (as it is not a public class FooSchema {} - @CordaSerializable public class FooSchemaV1 extends MappedSchema { FooSchemaV1() { super(FooSchema.class, 1, ImmutableList.of(PersistentFoo.class)); @@ -208,9 +207,8 @@ Instances of ``PersistentFoo`` can be persisted inside a flow as follows: .. sourcecode:: java PersistentFoo foo = new PersistentFoo(new UniqueIdentifier().getId().toString(), "Bar"); - node.getServices().withEntityManager(entityManager -> { + serviceHub.withEntityManager(entityManager -> { entityManager.persist(foo); - entityManager.flush(); return null; }); diff --git a/docs/source/api-vault-query.rst b/docs/source/api-vault-query.rst index 2243a6bfea..7b5c63e2ff 100644 --- a/docs/source/api-vault-query.rst +++ b/docs/source/api-vault-query.rst @@ -1,3 +1,9 @@ +.. highlight:: kotlin +.. raw:: html + + + + API: Vault Query ================ @@ -569,4 +575,78 @@ The Corda Tutorials provide examples satisfying these additional Use Cases: .. _JPQL: http://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#hql .. _JPA: https://docs.spring.io/spring-data/jpa/docs/current/reference/html +Mapping owning keys to external IDs +----------------------------------- +When creating new public keys via the ``KeyManagementService``, it is possible to create an association between the newly created public +key and an external ID. This, in effect, allows CorDapp developers to group state ownership/participation keys by an account ID. + +.. note:: This only works with freshly generated public keys and *not* the node's legal identity key. If you require that the freshly + generated keys be for the node's identity then use ``PersistentKeyManagementService.freshKeyAndCert`` instead of ``freshKey``. + Currently, the generation of keys for other identities is not supported. + +The code snippet below show how keys can be associated with an external ID by using the exposed JPA functionality: + +.. container:: codeset + + .. sourcecode:: java + + public AnonymousParty freshKeyForExternalId(UUID externalId, ServiceHub services) { + // Create a fresh key pair and return the public key. + AnonymousParty anonymousParty = freshKey(); + // Associate the fresh key to an external ID. + services.withEntityManager(entityManager -> { + PersistentKeyManagementService.PublicKeyHashToExternalId mapping = PersistentKeyManagementService.PublicKeyHashToExternalId(externalId, anonymousParty.owningKey); + entityManager.persist(mapping); + return null; + }); + return anonymousParty; + } + + .. sourcecode:: kotlin + + fun freshKeyForExternalId(externalId: UUID, services: ServiceHub): AnonymousParty { + // Create a fresh key pair and return the public key. + val anonymousParty = freshKey() + // Associate the fresh key to an external ID. + services.withEntityManager { + val mapping = PersistentKeyManagementService.PublicKeyHashToExternalId(externalId, anonymousParty.owningKey) + persist(mapping) + } + return anonymousParty + } + +As can be seen in the code snippet above, the ``PublicKeyHashToExternalId`` entity has been added to ``PersistentKeyManagementService``, +which allows you to associate your public keys with external IDs. So far, so good. + +.. note:: Here, it is worth noting that we must map **owning keys** to external IDs, as opposed to **state objects**. This is because it + might be the case that a ``LinearState`` is owned by two public keys generated by the same node. + +The intuition here is that when these public keys are used to own or participate in a state object, it is trivial to then associate those +states with a particular external ID. Behind the scenes, when states are persisted to the vault, the owning keys for each state are +persisted to a ``PersistentParty`` table. The ``PersistentParty`` table can be joined with the ``PublicKeyHashToExternalId`` table to create +a view which maps each state to one or more external IDs. The entity relationship diagram below helps to explain how this works. + +.. image:: resources/state-to-external-id.png + +When performing a vault query, it is now possible to query for states by external ID using a custom query criteria. + +.. container:: codeset + + .. sourcecode:: java + + UUID id = someExternalId; + FieldInfo externalIdField = getField("externalId", VaultSchemaV1.StateToExternalId.class); + CriteriaExpression externalId = Builder.equal(externalIdField, id); + QueryCriteria query = new VaultCustomQueryCriteria(externalId); + Vault.Page results = vaultService.queryBy(StateType.class, query); + + .. sourcecode:: kotlin + + val id: UUID = someExternalId + val externalId = builder { VaultSchemaV1.StateToExternalId::externalId.equal(id) } + val queryCriteria = QueryCriteria.VaultCustomQueryCriteria(externalId) + val results = vaultService.queryBy(queryCriteria).states + +The ``VaultCustomQueryCriteria`` can also be combined with other query criteria, like custom schemas, for instance. See the vault query API +examples above for how to combine ``QueryCriteria``. \ No newline at end of file diff --git a/docs/source/resources/state-to-external-id.png b/docs/source/resources/state-to-external-id.png new file mode 100644 index 0000000000000000000000000000000000000000..78cda151e4014f8df7dcc427c737fe45008e550a GIT binary patch literal 100647 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 { return AppendOnlyPersistentMap( diff --git a/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt b/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt index 1259adf2d8..5c9b99ef19 100644 --- a/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt +++ b/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt @@ -44,8 +44,8 @@ class NodeSchemaService(private val extraSchemas: Set = emptySet() PersistentIdentityService.PersistentIdentity::class.java, PersistentIdentityService.PersistentIdentityNames::class.java, ContractUpgradeServiceImpl.DBContractUpgrade::class.java, - RunOnceService.MutualExclusion::class.java - )){ + RunOnceService.MutualExclusion::class.java, + PersistentKeyManagementService.PublicKeyHashToExternalId::class.java) override val migrationResource = "node-core.changelog-master" } @@ -82,17 +82,11 @@ class NodeSchemaService(private val extraSchemas: Set = emptySet() // Because schema is always one supported by the state, just delegate. override fun generateMappedObject(state: ContractState, schema: MappedSchema): PersistentState { if ((schema === VaultSchemaV1) && (state is LinearState)) - return VaultSchemaV1.VaultLinearStates(state.linearId, state.participants) + return VaultSchemaV1.VaultLinearStates(state.linearId) if ((schema === VaultSchemaV1) && (state is FungibleAsset<*>)) - return VaultSchemaV1.VaultFungibleStates(state.owner, state.amount.quantity, state.amount.token.issuer.party, state.amount.token.issuer.reference, state.participants) + return VaultSchemaV1.VaultFungibleStates(state.owner, state.amount.quantity, state.amount.token.issuer.party, state.amount.token.issuer.reference) if ((schema === VaultSchemaV1) && (state is FungibleState<*>)) - return VaultSchemaV1.VaultFungibleStates( - participants = state.participants.toMutableSet(), - owner = null, - quantity = state.amount.quantity, - issuer = null, - issuerRef = null - ) + return VaultSchemaV1.VaultFungibleStates(owner = null, quantity = state.amount.quantity, issuer = null, issuerRef = null) return (state as QueryableState).generateMappedObject(schema) } diff --git a/node/src/main/kotlin/net/corda/node/services/vault/HibernateQueryCriteriaParser.kt b/node/src/main/kotlin/net/corda/node/services/vault/HibernateQueryCriteriaParser.kt index f4d912ffb1..e4aec418df 100644 --- a/node/src/main/kotlin/net/corda/node/services/vault/HibernateQueryCriteriaParser.kt +++ b/node/src/main/kotlin/net/corda/node/services/vault/HibernateQueryCriteriaParser.kt @@ -17,6 +17,7 @@ import net.corda.core.node.services.vault.NullOperator.NOT_NULL import net.corda.core.node.services.vault.QueryCriteria.CommonQueryCriteria import net.corda.core.schemas.PersistentState import net.corda.core.schemas.PersistentStateRef +import net.corda.core.schemas.StatePersistable import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.contextLogger import net.corda.core.utilities.trace @@ -222,7 +223,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class, Root<*>>(Pair(VaultSchemaV1.VaultStates::class.java, vaultStates)) + private val rootEntities = mutableMapOf, Root<*>>(Pair(VaultSchemaV1.VaultStates::class.java, vaultStates)) private val aggregateExpressions = mutableListOf>() private val commonPredicates = mutableMapOf, Predicate>() // schema attribute Name, operator -> predicate private val constraintPredicates = mutableSetOf() @@ -412,13 +413,25 @@ class HibernateQueryCriteriaParser(val contractStateType: Class("issuerRef").`in`(issuerRefs))) } - // participants + // Participants. criteria.participants?.let { - val participants = criteria.participants as List - val joinLinearStateToParty = vaultFungibleStates.joinSet("participants") - predicateSet.add(criteriaBuilder.and(joinLinearStateToParty.`in`(participants))) - criteriaQuery.distinct(true) + val participants = criteria.participants!! + + // Get the persistent party entity. + val persistentPartyEntity = VaultSchemaV1.PersistentParty::class.java + val entityRoot = rootEntities.getOrElse(persistentPartyEntity) { + val entityRoot = criteriaQuery.from(persistentPartyEntity) + rootEntities[persistentPartyEntity] = entityRoot + entityRoot + } + + // Add the join and participants predicates. + val statePartyJoin = criteriaBuilder.equal(vaultStates.get("stateRef"), entityRoot.get("stateRef")) + val participantsPredicate = criteriaBuilder.and(entityRoot.get("x500Name").`in`(participants)) + predicateSet.add(statePartyJoin) + predicateSet.add(participantsPredicate) } + return predicateSet } @@ -452,17 +465,29 @@ class HibernateQueryCriteriaParser(val contractStateType: Class("externalId").`in`(externalIds))) } - // deal participants + // Participants. criteria.participants?.let { - val participants = criteria.participants as List - val joinLinearStateToParty = vaultLinearStates.joinSet("participants") - predicateSet.add(criteriaBuilder.and(joinLinearStateToParty.`in`(participants))) - criteriaQuery.distinct(true) + val participants = criteria.participants!! + + // Get the persistent party entity. + val persistentPartyEntity = VaultSchemaV1.PersistentParty::class.java + val entityRoot = rootEntities.getOrElse(persistentPartyEntity) { + val entityRoot = criteriaQuery.from(persistentPartyEntity) + rootEntities[persistentPartyEntity] = entityRoot + entityRoot + } + + // Add the join and participants predicates. + val statePartyJoin = criteriaBuilder.equal(vaultStates.get("stateRef"), entityRoot.get("stateRef")) + val participantsPredicate = criteriaBuilder.and(entityRoot.get("x500Name").`in`(participants)) + predicateSet.add(statePartyJoin) + predicateSet.add(participantsPredicate) } + return predicateSet } - override fun parseCriteria(criteria: QueryCriteria.VaultCustomQueryCriteria): Collection { + override fun parseCriteria(criteria: QueryCriteria.VaultCustomQueryCriteria): Collection { log.trace { "Parsing VaultCustomQueryCriteria: $criteria" } val predicateSet = mutableSetOf() diff --git a/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt b/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt index 0bfefa0f0f..f83bdfecac 100644 --- a/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt +++ b/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt @@ -149,8 +149,15 @@ class NodeVaultService( // // Adding a new column in the "VaultStates" table was considered the best approach. val keys = stateOnly.participants.map { it.owningKey } + val persistentStateRef = PersistentStateRef(stateAndRef.key) val isRelevant = isRelevant(stateOnly, keyManagementService.filterMyKeys(keys).toSet()) val constraintInfo = Vault.ConstraintInfo(stateAndRef.value.state.constraint) + // Save a row for each party in the state_party table. + // TODO: Perhaps these can be stored in a batch? + stateOnly.participants.forEach { participant -> + val persistentParty = VaultSchemaV1.PersistentParty(persistentStateRef, participant) + session.save(persistentParty) + } val stateToAdd = VaultSchemaV1.VaultStates( notary = stateAndRef.value.state.notary, contractStateClassName = stateAndRef.value.state.data.javaClass.name, @@ -162,7 +169,7 @@ class NodeVaultService( constraintType = constraintInfo.type(), constraintData = constraintInfo.data() ) - stateToAdd.stateRef = PersistentStateRef(stateAndRef.key) + stateToAdd.stateRef = persistentStateRef session.save(stateToAdd) } if (consumedStateRefs.isNotEmpty()) { diff --git a/node/src/main/kotlin/net/corda/node/services/vault/VaultSchema.kt b/node/src/main/kotlin/net/corda/node/services/vault/VaultSchema.kt index db23815db2..b2cf297557 100644 --- a/node/src/main/kotlin/net/corda/node/services/vault/VaultSchema.kt +++ b/node/src/main/kotlin/net/corda/node/services/vault/VaultSchema.kt @@ -3,14 +3,18 @@ package net.corda.node.services.vault import net.corda.core.contracts.ContractState import net.corda.core.contracts.MAX_ISSUER_REF_SIZE import net.corda.core.contracts.UniqueIdentifier +import net.corda.core.crypto.toStringShort import net.corda.core.identity.AbstractParty import net.corda.core.identity.Party import net.corda.core.node.services.MAX_CONSTRAINT_DATA_SIZE import net.corda.core.node.services.Vault import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.PersistentState +import net.corda.core.schemas.PersistentStateRef +import net.corda.core.schemas.StatePersistable import net.corda.core.serialization.CordaSerializable import net.corda.core.utilities.OpaqueBytes +import org.hibernate.annotations.Immutable import org.hibernate.annotations.Type import java.time.Instant import java.util.* @@ -25,8 +29,18 @@ object VaultSchema * First version of the Vault ORM schema */ @CordaSerializable -object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, version = 1, - mappedTypes = listOf(VaultStates::class.java, VaultLinearStates::class.java, VaultFungibleStates::class.java, VaultTxnNote::class.java)) { +object VaultSchemaV1 : MappedSchema( + schemaFamily = VaultSchema.javaClass, + version = 1, + mappedTypes = listOf( + VaultStates::class.java, + VaultLinearStates::class.java, + VaultFungibleStates::class.java, + VaultTxnNote::class.java, + PersistentParty::class.java, + StateToExternalId::class.java + ) +) { override val migrationResource = "vault-schema.changelog-master" @@ -84,16 +98,6 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio class VaultLinearStates( /** [ContractState] attributes */ - /** X500Name of participant parties **/ - @ElementCollection - @CollectionTable(name = "vault_linear_states_parts", - joinColumns = [(JoinColumn(name = "output_index", referencedColumnName = "output_index")), (JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id"))], - foreignKey = ForeignKey(name = "FK__lin_stat_parts__lin_stat")) - @Column(name = "participants") - var participants: MutableSet? = null, - // Reason for not using Set is described here: - // https://stackoverflow.com/questions/44213074/kotlin-collection-has-neither-generic-type-or-onetomany-targetentity - /** * Represents a [LinearState] [UniqueIdentifier] */ @@ -104,25 +108,12 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio @Type(type = "uuid-char") var uuid: UUID ) : PersistentState() { - constructor(uid: UniqueIdentifier, _participants: List) : - this(externalId = uid.externalId, - uuid = uid.id, - participants = _participants.toMutableSet()) + constructor(uid: UniqueIdentifier) : this(externalId = uid.externalId, uuid = uid.id) } @Entity @Table(name = "vault_fungible_states") class VaultFungibleStates( - /** [ContractState] attributes */ - - /** X500Name of participant parties **/ - @ElementCollection - @CollectionTable(name = "vault_fungible_states_parts", - joinColumns = [(JoinColumn(name = "output_index", referencedColumnName = "output_index")), (JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id"))], - foreignKey = ForeignKey(name = "FK__fung_st_parts__fung_st")) - @Column(name = "participants", nullable = true) - var participants: MutableSet? = null, - /** [OwnableState] attributes */ /** X500Name of owner party **/ @@ -149,12 +140,8 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio @Type(type = "corda-wrapper-binary") var issuerRef: ByteArray? ) : PersistentState() { - constructor(_owner: AbstractParty, _quantity: Long, _issuerParty: AbstractParty, _issuerRef: OpaqueBytes, _participants: List) : - this(owner = _owner, - quantity = _quantity, - issuer = _issuerParty, - issuerRef = _issuerRef.bytes, - participants = _participants.toMutableSet()) + constructor(_owner: AbstractParty, _quantity: Long, _issuerParty: AbstractParty, _issuerRef: OpaqueBytes) : + this(owner = _owner, quantity = _quantity, issuer = _issuerParty, issuerRef = _issuerRef.bytes) } @Entity @@ -173,4 +160,47 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio ) { constructor(txId: String, note: String) : this(0, txId, note) } -} \ No newline at end of file + + @Entity + @Table(name = "state_party", indexes = [Index(name = "state_party_idx", columnList = "public_key_hash")]) + class PersistentParty( + @Id + @GeneratedValue + @Column(name = "id", unique = true, nullable = false) + var id: Long? = null, + + // Foreign key. + @Column(name = "state_ref") + var stateRef: PersistentStateRef, + + @Column(name = "public_key_hash", nullable = false) + var publicKeyHash: String, + + @Column(name = "x500_name", nullable = true) + var x500Name: AbstractParty? = null + ) : StatePersistable { + constructor(stateRef: PersistentStateRef, abstractParty: AbstractParty) + : this(null, stateRef, abstractParty.owningKey.toStringShort(), abstractParty) + } + + @Entity + @Immutable + @Table(name = "v_pkey_hash_ex_id_map") + class StateToExternalId( + @Id + @GeneratedValue + @Column(name = "id", unique = true, nullable = false) + var id: Long? = null, + + // Foreign key. + @Column(name = "state_ref") + var stateRef: PersistentStateRef, + + @Column(name = "public_key_hash") + var publicKeyHash: String, + + @Column(name = "external_id") + var externalId: UUID + ) : StatePersistable +} + diff --git a/node/src/main/resources/migration/vault-schema.changelog-master.xml b/node/src/main/resources/migration/vault-schema.changelog-master.xml index d1b1cd6f3d..9a049e261c 100644 --- a/node/src/main/resources/migration/vault-schema.changelog-master.xml +++ b/node/src/main/resources/migration/vault-schema.changelog-master.xml @@ -11,5 +11,6 @@ + diff --git a/node/src/main/resources/migration/vault-schema.changelog-v8.xml b/node/src/main/resources/migration/vault-schema.changelog-v8.xml new file mode 100644 index 0000000000..3f7adda2c2 --- /dev/null +++ b/node/src/main/resources/migration/vault-schema.changelog-v8.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + select + state_party.id, + state_party.public_key_hash, + state_party.transaction_id, + state_party.output_index, + pk_hash_to_ext_id_map.external_id + from state_party + join pk_hash_to_ext_id_map + on state_party.public_key_hash = pk_hash_to_ext_id_map.public_key_hash + + + diff --git a/node/src/test/kotlin/net/corda/node/services/vault/ExternalIdMappingTest.kt b/node/src/test/kotlin/net/corda/node/services/vault/ExternalIdMappingTest.kt new file mode 100644 index 0000000000..8e5b966e47 --- /dev/null +++ b/node/src/test/kotlin/net/corda/node/services/vault/ExternalIdMappingTest.kt @@ -0,0 +1,131 @@ +package net.corda.node.services.vault + +import com.nhaarman.mockito_kotlin.doReturn +import com.nhaarman.mockito_kotlin.whenever +import net.corda.core.identity.AbstractParty +import net.corda.core.identity.AnonymousParty +import net.corda.core.identity.CordaX500Name +import net.corda.core.node.services.queryBy +import net.corda.core.node.services.vault.QueryCriteria +import net.corda.core.node.services.vault.builder +import net.corda.core.transactions.TransactionBuilder +import net.corda.node.services.api.IdentityServiceInternal +import net.corda.node.services.keys.PersistentKeyManagementService +import net.corda.nodeapi.internal.persistence.CordaPersistence +import net.corda.testing.common.internal.testNetworkParameters +import net.corda.testing.contracts.DummyContract +import net.corda.testing.contracts.DummyState +import net.corda.testing.core.SerializationEnvironmentRule +import net.corda.testing.core.TestIdentity +import net.corda.testing.internal.rigorousMock +import net.corda.testing.node.MockServices +import org.junit.Rule +import org.junit.Test +import java.util.* +import kotlin.test.assertEquals + +class ExternalIdMappingTest { + + @Rule + @JvmField + val testSerialization = SerializationEnvironmentRule() + + private val cordapps = listOf( + "net.corda.node.services.persistence", + "net.corda.testing.contracts" + ) + + private val myself = TestIdentity(CordaX500Name("Me", "London", "GB")) + private val notary = TestIdentity(CordaX500Name("NotaryService", "London", "GB"), 1337L) + private val databaseAndServices = MockServices.makeTestDatabaseAndMockServices( + cordappPackages = cordapps, + identityService = rigorousMock().also { + doReturn(notary.party).whenever(it).partyFromKey(notary.publicKey) + doReturn(notary.party).whenever(it).wellKnownPartyFromAnonymous(notary.party) + doReturn(notary.party).whenever(it).wellKnownPartyFromX500Name(notary.name) + }, + initialIdentity = myself, + networkParameters = testNetworkParameters(minimumPlatformVersion = 4) + ) + + private val services: MockServices = databaseAndServices.second + private val database: CordaPersistence = databaseAndServices.first + + private fun freshKeyForExternalId(externalId: UUID): AnonymousParty { + val anonymousParty = freshKey() + database.transaction { + services.withEntityManager { + val mapping = PersistentKeyManagementService.PublicKeyHashToExternalId(externalId, anonymousParty.owningKey) + persist(mapping) + flush() + } + } + return anonymousParty + } + + private fun freshKey(): AnonymousParty { + val key = services.keyManagementService.freshKey() + val anonymousParty = AnonymousParty(key) + // Add behaviour to the mock identity management service for dealing with the new key. + // It won't be able to resolve it as it's just an anonymous key that is not linked to an identity. + services.identityService.also { doReturn(null).whenever(it).wellKnownPartyFromAnonymous(anonymousParty) } + return anonymousParty + } + + private fun createDummyState(participants: List): DummyState { + val tx = TransactionBuilder(notary = notary.party).apply { + addOutputState(DummyState(1, participants), DummyContract.PROGRAM_ID) + addCommand(DummyContract.Commands.Create(), participants.map { it.owningKey }) + } + val stx = services.signInitialTransaction(tx) + database.transaction { services.recordTransactions(stx) } + return stx.tx.outputsOfType().single() + } + + @Test + fun `Two states can be mapped to a single externalId`() { + val vaultService = services.vaultService + // Create new external ID and two keys mapped to it. + val id = UUID.randomUUID() + val keyOne = freshKeyForExternalId(id) + val keyTwo = freshKeyForExternalId(id) + // Create states with a public key assigned to the new external ID. + val dummyStateOne = createDummyState(listOf(keyOne)) + val dummyStateTwo = createDummyState(listOf(keyTwo)) + // This query should return two states! + val result = database.transaction { + val externalId = builder { VaultSchemaV1.StateToExternalId::externalId.`in`(listOf(id)) } + val queryCriteria = QueryCriteria.VaultCustomQueryCriteria(externalId) + vaultService.queryBy(queryCriteria).states + } + assertEquals(setOf(dummyStateOne, dummyStateTwo), result.map { it.state.data }.toSet()) + + // This query should return two states! + val resultTwo = database.transaction { + val externalId = builder { VaultSchemaV1.StateToExternalId::externalId.equal(id) } + val queryCriteria = QueryCriteria.VaultCustomQueryCriteria(externalId) + vaultService.queryBy(queryCriteria).states + } + assertEquals(setOf(dummyStateOne, dummyStateTwo), resultTwo.map { it.state.data }.toSet()) + } + + @Test + fun `One state can be mapped to multiple externalIds`() { + val vaultService = services.vaultService + // Create new external ID. + val idOne = UUID.randomUUID() + val keyOne = freshKeyForExternalId(idOne) + val idTwo = UUID.randomUUID() + val keyTwo = freshKeyForExternalId(idTwo) + // Create state with a public key assigned to the new external ID. + val dummyState = createDummyState(listOf(keyOne, keyTwo)) + // This query should return one state! + val result = database.transaction { + val externalId = builder { VaultSchemaV1.StateToExternalId::externalId.`in`(listOf(idOne, idTwo)) } + val queryCriteria = QueryCriteria.VaultCustomQueryCriteria(externalId) + vaultService.queryBy(queryCriteria).states + } + assertEquals(dummyState, result.single().state.data) + } + +} \ No newline at end of file