mirror of
https://github.com/corda/corda.git
synced 2024-12-24 07:06:44 +00:00
Merge commit '219624fba7e77765ede9ed6b84193736a448a553' into chrisr3-os-4-3-4.4-merge
This commit is contained in:
commit
c0eb8c03c0
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -5,7 +5,7 @@
|
||||
|
||||
- [ ] Have you run the unit, integration and smoke tests as described [here](https://docs.corda.net/head/testing.html)?
|
||||
- [ ] If you added public APIs, did you write the JavaDocs?
|
||||
- [ ] If the changes are of interest to application developers, have you added them to the [changelog](https://github.com/corda/corda/blob/master/docs/source/changelog.rst), and potentially the [release notes](https://github.com/corda/corda/blob/master/docs/source/release-notes.rst)?
|
||||
- [ ] If you are contributing for the first time, please read the agreement in [CONTRIBUTING.md](https://github.com/corda/corda/blob/master/CONTRIBUTING.md) now and add a comment to this pull request stating that your PR is in accordance with the [Developer's Certificate of Origin](https://github.com/corda/corda/blob/master/CONTRIBUTING.md#developer-certificate-of-origin).
|
||||
- [ ] If the changes are of interest to application developers, have you added them to the [changelog](https://docs.corda.net/head/changelog.html) (`/docs/source/changelog.rst`), and potentially the [release notes](https://docs.corda.net/head/release-notes.html) (`/docs/source/release-notes.rst`)?
|
||||
- [ ] If you are contributing for the first time, please read the [contributor agreement](https://docs.corda.net/head/contributing.html) now and add a comment to this pull request stating that your PR is in accordance with the [Developer's Certificate of Origin](https://docs.corda.net/head/contributing.html#merging-the-changes-back-into-corda).
|
||||
|
||||
Thanks for your code, it's appreciated! :)
|
||||
|
11
build.gradle
11
build.gradle
@ -117,8 +117,15 @@ buildscript {
|
||||
ext.picocli_version = '3.9.6'
|
||||
ext.commons_io_version = '2.6'
|
||||
ext.controlsfx_version = '8.40.15'
|
||||
ext.fontawesomefx_commons_version = '11.0'
|
||||
ext.fontawesomefx_fontawesome_version = '4.7.0-11'
|
||||
if (JavaVersion.current() == JavaVersion.VERSION_11) {
|
||||
// has been compiled by a more recent version of the Java Runtime (class file version 55.0)
|
||||
ext.fontawesomefx_commons_version = '11.0'
|
||||
ext.fontawesomefx_fontawesome_version = '4.7.0-11'
|
||||
}
|
||||
else {
|
||||
ext.fontawesomefx_commons_version = '8.15'
|
||||
ext.fontawesomefx_fontawesome_version = '4.7.0-5'
|
||||
}
|
||||
|
||||
// Name of the IntelliJ SDK created for the deterministic Java rt.jar.
|
||||
// ext.deterministic_idea_sdk = '1.8 (Deterministic)'
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package net.corda.core.internal
|
||||
|
||||
import co.paralleluniverse.strands.concurrent.ReentrantLock
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import io.github.classgraph.ClassGraph
|
||||
import io.github.classgraph.ScanResult
|
||||
import net.corda.core.DeleteForDJVM
|
||||
|
@ -178,6 +178,11 @@ interface IdentityService {
|
||||
@Suspendable
|
||||
fun externalIdForPublicKey(publicKey: PublicKey): UUID?
|
||||
|
||||
/**
|
||||
* This method returns all the [PublicKey]s which have been mapped to the supplied external ID.
|
||||
*
|
||||
* @param externalId the external ID to lookup [PublicKey]s for
|
||||
*/
|
||||
fun publicKeysForExternalId(externalId: UUID): Iterable<PublicKey>
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,17 @@ Unreleased
|
||||
when rethrown on the RPC client.
|
||||
|
||||
* Introduced a new parameter ``externalIds: List<UUID>`` to ``VaultQueryCriteria`` which allows CorDapp developers to constrain queries
|
||||
to a specified set of external IDs.
|
||||
to a specified set of external IDs. This feature should be used when querying states for a particular "account" (see accounts CorDapp for
|
||||
further information).
|
||||
|
||||
* Introduced a new API on ``KeyManagementService`` which facilitates lookups of ``PublicKey`` s to ``externalId`` s (Account IDs).
|
||||
* Introduced a new API on ``IdentityService`` called ``RegisterKey`` which maps a ``PublicKey`` to a specified ``CordaX500Name`` and to an
|
||||
optional ``UUID`` (external Id).
|
||||
|
||||
* Introduced a new API on ``IdentityService`` called ``publicKeyToExternalId` which facilitates lookups of ``PublicKey`` s to
|
||||
``externalId`` s (Account IDs).
|
||||
|
||||
* Introduced a new API on ``IdentityService`` called ``publicKeysForExternalId`` which returns all the ``PublicKey`` s associated with a
|
||||
particular external ID.
|
||||
|
||||
* ``StatePointer`` has been marked as ```@DoNotImplement``, which was an omission in the original release.
|
||||
|
||||
|
@ -6,6 +6,12 @@ apply plugin: 'net.corda.plugins.quasar-utils'
|
||||
configurations {
|
||||
integrationTestCompile.extendsFrom testCompile
|
||||
integrationTestRuntime.extendsFrom testRuntime
|
||||
|
||||
compile {
|
||||
// We already have a SLF4J implementation on our runtime classpath,
|
||||
// and we don't need another one.
|
||||
exclude group: "org.apache.logging.log4j"
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
@ -33,14 +39,9 @@ dependencies {
|
||||
|
||||
compile project(':core')
|
||||
compile project(':client:jfx')
|
||||
compile (project(':node-driver')) {
|
||||
// We already have a SLF4J implementation on our runtime classpath,
|
||||
// and we don't need another one.
|
||||
exclude group: 'org.apache.logging.log4j'
|
||||
}
|
||||
compile (project(':webserver')) {
|
||||
exclude group: "org.apache.logging.log4j"
|
||||
}
|
||||
compile project(':node-driver')
|
||||
compile project(':webserver')
|
||||
|
||||
testCompile project(':test-utils')
|
||||
|
||||
compile "org.graphstream:gs-core:1.3"
|
||||
@ -49,8 +50,8 @@ dependencies {
|
||||
exclude group: "junit"
|
||||
}
|
||||
|
||||
compile project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
cordaRuntime project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
cordaRuntime project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
|
||||
// CorDapps: dependent flows and services
|
||||
compile project(':finance:contracts')
|
||||
|
@ -111,7 +111,6 @@ object PersistentIdentitiesMigrationSchemaBuilder {
|
||||
PersistentIdentityService.PersistentPartyToPublicKeyHash::class.java,
|
||||
PersistentIdentityService.PersistentPublicKeyHashToParty::class.java,
|
||||
PersistentIdentityService.PersistentHashToPublicKey::class.java,
|
||||
BasicHSMKeyManagementService.PersistentKey::class.java,
|
||||
NodeAttachmentService.DBAttachment::class.java,
|
||||
DBNetworkParametersStorage.PersistentNetworkParameters::class.java
|
||||
))
|
||||
|
@ -129,7 +129,6 @@ object VaultMigrationSchemaV1 : MappedSchema(schemaFamily = VaultMigrationSchema
|
||||
PersistentIdentityService.PersistentPublicKeyHashToCertificate::class.java,
|
||||
PersistentIdentityService.PersistentPartyToPublicKeyHash::class.java,
|
||||
PersistentIdentityService.PersistentPublicKeyHashToParty::class.java,
|
||||
PersistentIdentityService.PersistentHashToPublicKey::class.java,
|
||||
BasicHSMKeyManagementService.PersistentKey::class.java,
|
||||
NodeAttachmentService.DBAttachment::class.java,
|
||||
DBNetworkParametersStorage.PersistentNetworkParameters::class.java
|
||||
|
@ -27,6 +27,7 @@ import net.corda.node.services.persistence.NodeAttachmentService
|
||||
import org.hibernate.query.criteria.internal.expression.LiteralExpression
|
||||
import org.hibernate.query.criteria.internal.path.SingularAttributePath
|
||||
import org.hibernate.query.criteria.internal.predicate.ComparisonPredicate
|
||||
import org.hibernate.query.criteria.internal.predicate.CompoundPredicate
|
||||
import org.hibernate.query.criteria.internal.predicate.InPredicate
|
||||
import java.security.PublicKey
|
||||
import java.time.Instant
|
||||
@ -409,63 +410,74 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
||||
}
|
||||
}
|
||||
|
||||
private fun getVaultFungibleStateRoot(): Root<out Any> {
|
||||
val entityStateClass = VaultSchemaV1.VaultFungibleStates::class.java
|
||||
return rootEntities.getOrElse(entityStateClass) {
|
||||
val entityRoot = criteriaQuery.from(entityStateClass)
|
||||
rootEntities[entityStateClass] = entityRoot
|
||||
entityRoot
|
||||
}
|
||||
}
|
||||
|
||||
private fun getVaultLinearStatesRoot(): Root<out Any> {
|
||||
val entityStateClass = VaultSchemaV1.VaultLinearStates::class.java
|
||||
return rootEntities.getOrElse(entityStateClass) {
|
||||
val entityRoot = criteriaQuery.from(entityStateClass)
|
||||
rootEntities[entityStateClass] = entityRoot
|
||||
entityRoot
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPersistentPartyRoot(): Root<out Any> {
|
||||
val persistentPartyEntity = VaultSchemaV1.PersistentParty::class.java
|
||||
return rootEntities.getOrElse(persistentPartyEntity) {
|
||||
val entityRoot = criteriaQuery.from(persistentPartyEntity)
|
||||
rootEntities[persistentPartyEntity] = entityRoot
|
||||
entityRoot
|
||||
}
|
||||
}
|
||||
|
||||
override fun parseCriteria(criteria: QueryCriteria.FungibleAssetQueryCriteria): Collection<Predicate> {
|
||||
log.trace { "Parsing FungibleAssetQueryCriteria: $criteria" }
|
||||
|
||||
val predicateSet = mutableSetOf<Predicate>()
|
||||
|
||||
// ensure we re-use any existing instance of the same root entity
|
||||
val entityStateClass = VaultSchemaV1.VaultFungibleStates::class.java
|
||||
val vaultFungibleStates =
|
||||
rootEntities.getOrElse(entityStateClass) {
|
||||
val entityRoot = criteriaQuery.from(entityStateClass)
|
||||
rootEntities[entityStateClass] = entityRoot
|
||||
entityRoot
|
||||
}
|
||||
|
||||
val joinPredicate = criteriaBuilder.equal(vaultStates.get<PersistentStateRef>("stateRef"), vaultFungibleStates.get<PersistentStateRef>("stateRef"))
|
||||
val vaultFungibleStatesRoot = getVaultFungibleStateRoot()
|
||||
val joinPredicate = criteriaBuilder.equal(vaultStates.get<PersistentStateRef>("stateRef"),
|
||||
vaultFungibleStatesRoot.get<PersistentStateRef>("stateRef"))
|
||||
predicateSet.add(joinPredicate)
|
||||
|
||||
// owner
|
||||
criteria.owner?.let {
|
||||
val owners = criteria.owner as List<AbstractParty>
|
||||
predicateSet.add(criteriaBuilder.and(vaultFungibleStates.get<AbstractParty>("owner").`in`(owners)))
|
||||
predicateSet.add(criteriaBuilder.and(vaultFungibleStatesRoot.get<AbstractParty>("owner").`in`(owners)))
|
||||
}
|
||||
|
||||
// quantity
|
||||
criteria.quantity?.let {
|
||||
predicateSet.add(columnPredicateToPredicate(vaultFungibleStates.get<Long>("quantity"), it))
|
||||
predicateSet.add(columnPredicateToPredicate(vaultFungibleStatesRoot.get<Long>("quantity"), it))
|
||||
}
|
||||
|
||||
// issuer party
|
||||
criteria.issuer?.let {
|
||||
val issuerParties = criteria.issuer as List<AbstractParty>
|
||||
predicateSet.add(criteriaBuilder.and(vaultFungibleStates.get<AbstractParty>("issuer").`in`(issuerParties)))
|
||||
predicateSet.add(criteriaBuilder.and(vaultFungibleStatesRoot.get<AbstractParty>("issuer").`in`(issuerParties)))
|
||||
}
|
||||
|
||||
// issuer reference
|
||||
criteria.issuerRef?.let {
|
||||
val issuerRefs = (criteria.issuerRef as List<OpaqueBytes>).map { it.bytes }
|
||||
predicateSet.add(criteriaBuilder.and(vaultFungibleStates.get<ByteArray>("issuerRef").`in`(issuerRefs)))
|
||||
predicateSet.add(criteriaBuilder.and(vaultFungibleStatesRoot.get<ByteArray>("issuerRef").`in`(issuerRefs)))
|
||||
}
|
||||
|
||||
// Participants.
|
||||
criteria.participants?.let {
|
||||
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<VaultSchemaV1.VaultStates>("stateRef"), entityRoot.get<VaultSchemaV1.PersistentParty>("compositeKey").get<PersistentStateRef>("stateRef"))
|
||||
val participantsPredicate = criteriaBuilder.and(entityRoot.get<VaultSchemaV1.PersistentParty>("x500Name").`in`(participants))
|
||||
predicateSet.add(statePartyJoin)
|
||||
predicateSet.add(participantsPredicate)
|
||||
// Join VaultFungibleState and PersistentParty tables (participant values are added to the common query criteria predicate)
|
||||
val statePartyToFungibleStatesJoin = criteriaBuilder.and(
|
||||
criteriaBuilder.equal(vaultFungibleStatesRoot.get<VaultSchemaV1.VaultFungibleStates>("stateRef"),
|
||||
getPersistentPartyRoot().get<VaultSchemaV1.PersistentParty>("compositeKey").get<PersistentStateRef>("stateRef")))
|
||||
predicateSet.add(statePartyToFungibleStatesJoin)
|
||||
}
|
||||
|
||||
return predicateSet
|
||||
@ -477,47 +489,32 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
||||
val predicateSet = mutableSetOf<Predicate>()
|
||||
|
||||
// ensure we re-use any existing instance of the same root entity
|
||||
val entityStateClass = VaultSchemaV1.VaultLinearStates::class.java
|
||||
val vaultLinearStates =
|
||||
rootEntities.getOrElse(entityStateClass) {
|
||||
val entityRoot = criteriaQuery.from(entityStateClass)
|
||||
rootEntities[entityStateClass] = entityRoot
|
||||
entityRoot
|
||||
}
|
||||
val vaultLinearStatesRoot = getVaultLinearStatesRoot()
|
||||
|
||||
val joinPredicate = criteriaBuilder.equal(vaultStates.get<PersistentStateRef>("stateRef"), vaultLinearStates.get<PersistentStateRef>("stateRef"))
|
||||
val joinPredicate = criteriaBuilder.equal(vaultStates.get<PersistentStateRef>("stateRef"),
|
||||
vaultLinearStatesRoot.get<PersistentStateRef>("stateRef"))
|
||||
predicateSet.add(joinPredicate)
|
||||
|
||||
// linear ids UUID
|
||||
criteria.uuid?.let {
|
||||
val uuids = criteria.uuid as List<UUID>
|
||||
predicateSet.add(criteriaBuilder.and(vaultLinearStates.get<UUID>("uuid").`in`(uuids)))
|
||||
predicateSet.add(criteriaBuilder.and(vaultLinearStatesRoot.get<UUID>("uuid").`in`(uuids)))
|
||||
}
|
||||
|
||||
// linear ids externalId
|
||||
criteria.externalId?.let {
|
||||
val externalIds = criteria.externalId as List<String>
|
||||
if (externalIds.isNotEmpty())
|
||||
predicateSet.add(criteriaBuilder.and(vaultLinearStates.get<String>("externalId").`in`(externalIds)))
|
||||
predicateSet.add(criteriaBuilder.and(vaultLinearStatesRoot.get<String>("externalId").`in`(externalIds)))
|
||||
}
|
||||
|
||||
// Participants.
|
||||
criteria.participants?.let {
|
||||
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<VaultSchemaV1.VaultStates>("stateRef"), entityRoot.get<VaultSchemaV1.PersistentParty>("compositeKey").get<PersistentStateRef>("stateRef"))
|
||||
val participantsPredicate = criteriaBuilder.and(entityRoot.get<VaultSchemaV1.PersistentParty>("x500Name").`in`(participants))
|
||||
predicateSet.add(statePartyJoin)
|
||||
predicateSet.add(participantsPredicate)
|
||||
// Join VaultLinearState and PersistentParty tables (participant values are added to the common query criteria predicate)
|
||||
val statePartyToLinearStatesJoin = criteriaBuilder.and(
|
||||
criteriaBuilder.equal(vaultLinearStatesRoot.get<VaultSchemaV1.VaultLinearStates>("stateRef"),
|
||||
getPersistentPartyRoot().get<VaultSchemaV1.PersistentParty>("compositeKey").get<PersistentStateRef>("stateRef")))
|
||||
predicateSet.add(statePartyToLinearStatesJoin)
|
||||
}
|
||||
|
||||
return predicateSet
|
||||
@ -678,6 +675,33 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
||||
constraintPredicates.add(externalIdPredicate)
|
||||
}
|
||||
|
||||
// Participants.
|
||||
criteria.participants?.let {
|
||||
val participants = criteria.participants!!
|
||||
|
||||
// use a single predicate for querying the persistent party table (incrementally add additional parties)
|
||||
val predicateID = Pair(VaultSchemaV1.PersistentParty::x500Name.name, EQUAL)
|
||||
if (commonPredicates.containsKey(predicateID)) {
|
||||
val existingParticipants = ((((commonPredicates[predicateID]) as CompoundPredicate).expressions[0]) as InPredicate<*>)
|
||||
.values.map { participant -> (participant as LiteralExpression<*>).literal }
|
||||
log.warn("Adding new participants: $participants to existing participants: $existingParticipants")
|
||||
commonPredicates.replace(predicateID, criteriaBuilder.and(
|
||||
getPersistentPartyRoot().get<VaultSchemaV1.PersistentParty>("x500Name").`in`(existingParticipants + participants)))
|
||||
}
|
||||
else {
|
||||
// Get the persistent party entity.
|
||||
commonPredicates[predicateID] = criteriaBuilder.and(
|
||||
getPersistentPartyRoot().get<VaultSchemaV1.PersistentParty>("x500Name").`in`(participants))
|
||||
}
|
||||
|
||||
// Add the join for vault states to persistent entities (if this is not a Fungible nor Linear criteria query)
|
||||
if (criteria !is QueryCriteria.FungibleAssetQueryCriteria && criteria !is QueryCriteria.LinearStateQueryCriteria ) {
|
||||
val statePartyJoin = criteriaBuilder.equal(vaultStates.get<VaultSchemaV1.VaultStates>("stateRef"),
|
||||
getPersistentPartyRoot().get<VaultSchemaV1.PersistentParty>("compositeKey").get<PersistentStateRef>("stateRef"))
|
||||
constraintPredicates.add(statePartyJoin)
|
||||
}
|
||||
}
|
||||
|
||||
return emptySet()
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,13 @@
|
||||
<include file="migration/node-core.changelog-v13.xml"/>
|
||||
<!-- This change should be done before the v14-data migration. -->
|
||||
<include file="migration/node-core.changelog-v15-table.xml"/>
|
||||
<include file="migration/node-core.changelog-v14-data.xml"/>
|
||||
<include file="migration/node-core.changelog-v15.xml"/>
|
||||
|
||||
<include file="migration/node-core.changelog-v16.xml"/>
|
||||
|
||||
<!-- This must run after node-core.changelog-init.xml, to prevent database columns being created twice. -->
|
||||
<include file="migration/vault-schema.changelog-v9.xml"/>
|
||||
|
||||
<include file="migration/node-core.changelog-v14-data.xml"/>
|
||||
|
||||
</databaseChangeLog>
|
||||
|
@ -0,0 +1,21 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
|
||||
<changeSet author="R3.Corda" id="modify public_key column type" dbms="postgresql">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<sqlCheck expectedResult="bytea">
|
||||
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'node_hash_to_key' AND COLUMN_NAME = 'public_key'
|
||||
</sqlCheck>
|
||||
</not>
|
||||
</preConditions>
|
||||
<dropColumn tableName="node_hash_to_key" columnName="public_key"/>
|
||||
<addColumn tableName="node_hash_to_key">
|
||||
<column name="public_key" type="varbinary(64000)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
@ -229,6 +229,34 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
|
||||
* Query API tests
|
||||
*/
|
||||
|
||||
/** Generic Query tests: using CommonQueryCriteria */
|
||||
|
||||
@Test
|
||||
fun `unconsumed base contract states for single participant`() {
|
||||
database.transaction {
|
||||
identitySvc.verifyAndRegisterIdentity(BIG_CORP_IDENTITY)
|
||||
vaultFiller.fillWithDummyState(participants = listOf(MEGA_CORP, MINI_CORP))
|
||||
vaultFiller.fillWithDummyState(participants = listOf(MEGA_CORP))
|
||||
vaultFiller.fillWithDummyState(participants = listOf(MEGA_CORP, BIG_CORP)) // true
|
||||
val criteria = VaultQueryCriteria(participants = listOf(BIG_CORP))
|
||||
val results = vaultService.queryBy<ContractState>(criteria)
|
||||
assertThat(results.states).hasSize(1)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `unconsumed base contract states for two participants`() {
|
||||
database.transaction {
|
||||
identitySvc.verifyAndRegisterIdentity(BIG_CORP_IDENTITY)
|
||||
vaultFiller.fillWithDummyState(participants = listOf(MEGA_CORP, MINI_CORP)) // true
|
||||
vaultFiller.fillWithDummyState(participants = listOf(MEGA_CORP, BIG_CORP)) // true
|
||||
vaultFiller.fillWithDummyState(participants = listOf(MEGA_CORP))
|
||||
val criteria = VaultQueryCriteria(participants = listOf(MINI_CORP, BIG_CORP))
|
||||
val results = vaultService.queryBy<ContractState>(criteria)
|
||||
assertThat(results.states).hasSize(2)
|
||||
}
|
||||
}
|
||||
|
||||
/** Generic Query tests
|
||||
(combining both FungibleState and LinearState contract types) */
|
||||
|
||||
@ -2379,8 +2407,8 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
|
||||
identitySvc.verifyAndRegisterIdentity(BOB_IDENTITY)
|
||||
identitySvc.verifyAndRegisterIdentity(CHARLIE_IDENTITY)
|
||||
vaultFiller.fillWithSomeTestLinearStates(1, "TEST1", listOf(ALICE))
|
||||
vaultFiller.fillWithSomeTestLinearStates(1, "TEST2", listOf(BOB))
|
||||
vaultFiller.fillWithSomeTestLinearStates(1, "TEST3", listOf(CHARLIE))
|
||||
vaultFiller.fillWithSomeTestLinearStates(1, "TEST2", listOf(BOB))
|
||||
vaultFiller.fillWithSomeTestLinearStates(1, "TEST3", listOf(CHARLIE))
|
||||
vaultFiller.fillWithSomeTestCash(100.DOLLARS, notaryServices, 1, DUMMY_CASH_ISSUER)
|
||||
vaultFiller.fillWithSomeTestCommodity(Amount(100, Commodity.getInstance("FCOJ")!!), notaryServices, DUMMY_OBLIGATION_ISSUER.ref(1))
|
||||
vaultFiller.fillWithDummyState()
|
||||
@ -2397,7 +2425,11 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
|
||||
assertThat(resultsFASC.states).hasSize(2)
|
||||
// composite query for both linear and fungible asset states by participants
|
||||
val resultsComposite = vaultService.queryBy<ContractState>(linearStateCriteria.or(fungibleAssetStateCriteria))
|
||||
assertThat(resultsComposite.states).hasSize(4)
|
||||
assertThat(resultsComposite.states).hasSize(5)
|
||||
// composite query both linear and fungible and dummy asset states by participants
|
||||
val commonQueryCriteria = VaultQueryCriteria(participants = listOf(MEGA_CORP))
|
||||
val resultsAll = vaultService.queryBy<ContractState>(linearStateCriteria.or(fungibleAssetStateCriteria).or(commonQueryCriteria))
|
||||
assertThat(resultsAll.states).hasSize(6)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import net.corda.core.utilities.contextLogger
|
||||
import net.corda.core.utilities.debug
|
||||
import net.corda.core.utilities.loggerFor
|
||||
import net.corda.core.utilities.trace
|
||||
import net.corda.serialization.internal.model.resolveAgainst
|
||||
import org.apache.qpid.proton.amqp.Symbol
|
||||
import org.apache.qpid.proton.codec.Data
|
||||
import java.lang.reflect.Type
|
||||
@ -37,20 +38,21 @@ open class ArraySerializer(override val type: Type, factory: LocalSerializerFact
|
||||
private fun calcTypeName(type: Type, debugOffset : Int = 0): String {
|
||||
logger.trace { "${"".padStart(debugOffset, ' ') } calcTypeName - ${type.typeName}" }
|
||||
|
||||
return if (type.componentType().isArray()) {
|
||||
val componentType = type.componentType()
|
||||
return if (componentType.isArray()) {
|
||||
// Special case handler for primitive byte arrays. This is needed because we can silently
|
||||
// coerce a byte[] to our own binary type. Normally, if the component type was itself an
|
||||
// array we'd keep walking down the chain but for byte[] stop here and use binary instead
|
||||
val typeName = if (AMQPTypeIdentifiers.isPrimitive(type.componentType())) {
|
||||
AMQPTypeIdentifiers.nameForType(type.componentType())
|
||||
val typeName = if (AMQPTypeIdentifiers.isPrimitive(componentType)) {
|
||||
AMQPTypeIdentifiers.nameForType(componentType)
|
||||
} else {
|
||||
calcTypeName(type.componentType(), debugOffset + 4)
|
||||
calcTypeName(componentType, debugOffset + 4)
|
||||
}
|
||||
|
||||
"$typeName[]"
|
||||
} else {
|
||||
val arrayType = if (type.asClass().componentType.isPrimitive) "[p]" else "[]"
|
||||
"${type.componentType().typeName}$arrayType"
|
||||
"${componentType.typeName}$arrayType"
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,7 +60,7 @@ open class ArraySerializer(override val type: Type, factory: LocalSerializerFact
|
||||
factory.createDescriptor(type)
|
||||
}
|
||||
|
||||
internal val elementType: Type by lazy { type.componentType() }
|
||||
internal val elementType: Type by lazy { type.componentType().resolveAgainst(type) }
|
||||
internal open val typeName by lazy { calcTypeName(type) }
|
||||
|
||||
internal val typeNotation: TypeNotation by lazy {
|
||||
|
@ -209,7 +209,12 @@ internal data class LocalTypeInformationBuilder(val lookup: LocalTypeLookup,
|
||||
observedType = type,
|
||||
typeIdentifier = typeIdentifier,
|
||||
constructor = null,
|
||||
properties = buildReadOnlyProperties(rawType),
|
||||
properties = if (rawType == Class::class.java) {
|
||||
// Do NOT drill down into the internals of java.lang.Class.
|
||||
emptyMap()
|
||||
} else {
|
||||
buildReadOnlyProperties(rawType)
|
||||
},
|
||||
superclass = superclassInformation,
|
||||
interfaces = interfaceInformation,
|
||||
typeParameters = typeParameterInformation,
|
||||
|
@ -224,15 +224,16 @@ class VaultFiller @JvmOverloads constructor(
|
||||
/**
|
||||
* Records a dummy state in the Vault (useful for creating random states when testing vault queries)
|
||||
*/
|
||||
fun fillWithDummyState() : Vault<DummyState> {
|
||||
fun fillWithDummyState(participants: List<AbstractParty> = listOf(services.myInfo.singleIdentity())) : Vault<DummyState> {
|
||||
val outputState = TransactionState(
|
||||
data = DummyState(Random().nextInt(), participants = listOf(services.myInfo.singleIdentity())),
|
||||
data = DummyState(Random().nextInt(), participants = participants),
|
||||
contract = DummyContract.PROGRAM_ID,
|
||||
notary = defaultNotary.party
|
||||
)
|
||||
val participantKeys : List<PublicKey> = participants.map { it.owningKey }
|
||||
val builder = TransactionBuilder()
|
||||
.addOutputState(outputState)
|
||||
.addCommand(DummyCommandData, defaultNotary.party.owningKey)
|
||||
.addCommand(DummyCommandData, participantKeys)
|
||||
val stxn = services.signInitialTransaction(builder)
|
||||
services.recordTransactions(stxn)
|
||||
return Vault(setOf(stxn.tx.outRef(0)))
|
||||
|
@ -40,7 +40,7 @@ task buildWebserverJar(type: FatCapsule, dependsOn: project(':node').tasks.jar)
|
||||
|
||||
capsuleManifest {
|
||||
applicationVersion = corda_release_version
|
||||
javaAgents = ["quasar-core-${quasar_version}.jar"]
|
||||
javaAgents = quasar_classifier == null ? ["quasar-core-${quasar_version}.jar"] : ["quasar-core-${quasar_version}-${quasar_classifier}.jar"]
|
||||
systemProperties['visualvm.display.name'] = 'Corda Webserver'
|
||||
minJavaVersion = '1.8.0'
|
||||
minUpdateVersion['1.8'] = java8_minUpdateVersion
|
||||
|
Loading…
Reference in New Issue
Block a user