Vault identity cleanup (#1194)

* Removed notary_key (and all references) from vault schema.
Fixed incorrect NOTARY usage in certain tests (cash consumption)

* Fixed broken test.

* Replace CommonSchemaV1.Party in all VaultSchema tables (and associated queries) with string'ified X500Name's only.

* Fix broken tests.

* Completely remove CommonSchemaV1.Party and all references (in favour of X500Name's)

* Updated all schema attribute identity references to use AbstractParty.

* Updated all schema attribute identity references to use AbstractParty.

* Standarised attribute naming for parties (removed 'Name')

* Updated deprecate identity API references following rebase.

* Configurable IdentityService as a lambda in JUnit tests.

* Additional WARNING logging to enable troubleshooting of identity lookup failures.

* Final identity updates to sample schemas.
Cleaned up several compiler warnings.
This commit is contained in:
josecoll
2017-08-17 09:30:27 +01:00
committed by GitHub
parent dc8d232480
commit 48e8aa55fa
33 changed files with 237 additions and 173 deletions

View File

@ -5,6 +5,7 @@ import net.corda.core.concurrent.CordaFuture
import net.corda.core.contracts.* import net.corda.core.contracts.*
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.flows.FlowException import net.corda.core.flows.FlowException
import net.corda.core.identity.AbstractParty
import net.corda.core.node.services.vault.QueryCriteria import net.corda.core.node.services.vault.QueryCriteria
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.toFuture import net.corda.core.toFuture
@ -135,8 +136,7 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
val recordedTime: Instant, val recordedTime: Instant,
val consumedTime: Instant?, val consumedTime: Instant?,
val status: Vault.StateStatus, val status: Vault.StateStatus,
val notaryName: String, val notary: AbstractParty?,
val notaryKey: String,
val lockId: String?, val lockId: String?,
val lockUpdateTime: Instant?) val lockUpdateTime: Instant?)
} }

View File

@ -51,7 +51,7 @@ sealed class QueryCriteria {
data class VaultQueryCriteria @JvmOverloads constructor (override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, data class VaultQueryCriteria @JvmOverloads constructor (override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED,
val contractStateTypes: Set<Class<out ContractState>>? = null, val contractStateTypes: Set<Class<out ContractState>>? = null,
val stateRefs: List<StateRef>? = null, val stateRefs: List<StateRef>? = null,
val notaryName: List<X500Name>? = null, val notary: List<AbstractParty>? = null,
val softLockingCondition: SoftLockingCondition? = null, val softLockingCondition: SoftLockingCondition? = null,
val timeCondition: TimeCondition? = null) : CommonQueryCriteria() { val timeCondition: TimeCondition? = null) : CommonQueryCriteria() {
override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> { override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> {
@ -81,7 +81,7 @@ sealed class QueryCriteria {
data class FungibleAssetQueryCriteria @JvmOverloads constructor(val participants: List<AbstractParty>? = null, data class FungibleAssetQueryCriteria @JvmOverloads constructor(val participants: List<AbstractParty>? = null,
val owner: List<AbstractParty>? = null, val owner: List<AbstractParty>? = null,
val quantity: ColumnPredicate<Long>? = null, val quantity: ColumnPredicate<Long>? = null,
val issuerPartyName: List<AbstractParty>? = null, val issuer: List<AbstractParty>? = null,
val issuerRef: List<OpaqueBytes>? = null, val issuerRef: List<OpaqueBytes>? = null,
override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED) : CommonQueryCriteria() { override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED) : CommonQueryCriteria() {
override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> { override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> {

View File

@ -151,7 +151,7 @@ data class Sort(val columns: Collection<SortColumn>) {
enum class VaultStateAttribute(val attributeName: String) : Attribute { enum class VaultStateAttribute(val attributeName: String) : Attribute {
/** Vault States */ /** Vault States */
NOTARY_NAME("notaryName"), NOTARY_NAME("notary"),
CONTRACT_TYPE("contractStateClassName"), CONTRACT_TYPE("contractStateClassName"),
STATE_STATUS("stateStatus"), STATE_STATUS("stateStatus"),
RECORDED_TIME("recordedTime"), RECORDED_TIME("recordedTime"),

View File

@ -17,10 +17,17 @@ object CommonSchema
/** /**
* First version of the Vault ORM schema * First version of the Vault ORM schema
*/ */
object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, version = 1, mappedTypes = listOf(Party::class.java)) { object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, version = 1, mappedTypes = emptyList()) {
@MappedSuperclass @MappedSuperclass
open class LinearState( open class LinearState(
/** [ContractState] attributes */
/** X500Name of participant parties **/
@ElementCollection
@Column(name = "participants")
var participants: MutableSet<AbstractParty>? = null,
/** /**
* Represents a [LinearState] [UniqueIdentifier] * Represents a [LinearState] [UniqueIdentifier]
*/ */
@ -31,18 +38,26 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers
var uuid: UUID var uuid: UUID
) : PersistentState() { ) : PersistentState() {
constructor(uid: UniqueIdentifier) : this(externalId = uid.externalId, uuid = uid.id) constructor(uid: UniqueIdentifier, _participants: Set<AbstractParty>)
: this(participants = _participants.toMutableSet(),
externalId = uid.externalId,
uuid = uid.id)
} }
@MappedSuperclass @MappedSuperclass
open class FungibleState( open class FungibleState(
/** [ContractState] attributes */ /** [ContractState] attributes */
@OneToMany(cascade = arrayOf(CascadeType.ALL))
var participants: Set<CommonSchemaV1.Party>, /** X500Name of participant parties **/
@ElementCollection
@Column(name = "participants")
var participants: MutableSet<AbstractParty>? = null,
/** [OwnableState] attributes */ /** [OwnableState] attributes */
@OneToOne(cascade = arrayOf(CascadeType.ALL))
var ownerKey: CommonSchemaV1.Party, /** X500Name of owner party **/
@Column(name = "owner_name")
var owner: AbstractParty,
/** [FungibleAsset] attributes /** [FungibleAsset] attributes
* *
@ -55,42 +70,12 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers
var quantity: Long, var quantity: Long,
/** Issuer attributes */ /** Issuer attributes */
@OneToOne(cascade = arrayOf(CascadeType.ALL))
var issuerParty: CommonSchemaV1.Party, /** X500Name of issuer party **/
@Column(name = "issuer_name")
var issuer: AbstractParty,
@Column(name = "issuer_reference") @Column(name = "issuer_reference")
var issuerRef: ByteArray var issuerRef: ByteArray
) : PersistentState() { ) : PersistentState()
constructor(_participants: Set<AbstractParty>, _ownerKey: AbstractParty, _quantity: Long, _issuerParty: AbstractParty, _issuerRef: ByteArray)
: this(participants = _participants.map { CommonSchemaV1.Party(it) }.toSet(),
ownerKey = CommonSchemaV1.Party(_ownerKey),
quantity = _quantity,
issuerParty = CommonSchemaV1.Party(_issuerParty),
issuerRef = _issuerRef)
}
/**
* Party entity (to be replaced by referencing final Identity Schema)
*/
@Entity
@Table(name = "vault_party",
indexes = arrayOf(Index(name = "party_name_idx", columnList = "party_name")))
class Party(
@Id
@GeneratedValue
@Column(name = "party_id")
var id: Int,
/**
* [Party] attributes
*/
@Column(name = "party_name")
var name: String,
@Column(name = "party_key", length = 65535) // TODO What is the upper limit on size of CompositeKey?)
var key: String
) {
constructor(party: AbstractParty)
: this(0, party.nameOrNull()?.toString() ?: party.toString(), party.owningKey.toBase58String())
}
} }

View File

@ -2,6 +2,7 @@ package net.corda.core.schemas.converters
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.node.services.IdentityService import net.corda.core.node.services.IdentityService
import net.corda.core.utilities.loggerFor
import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.asn1.x500.X500Name
import javax.persistence.AttributeConverter import javax.persistence.AttributeConverter
import javax.persistence.Converter import javax.persistence.Converter
@ -17,9 +18,15 @@ class AbstractPartyToX500NameAsStringConverter(identitySvc: () -> IdentityServic
identitySvc() identitySvc()
} }
companion object {
val log = loggerFor<AbstractPartyToX500NameAsStringConverter>()
}
override fun convertToDatabaseColumn(party: AbstractParty?): String? { override fun convertToDatabaseColumn(party: AbstractParty?): String? {
party?.let { party?.let {
return identityService.partyFromAnonymous(party)?.toString() val partyName = identityService.partyFromAnonymous(party)?.toString()
if (partyName != null) return partyName
else log.warn ("Identity service unable to resolve AbstractParty: $party")
} }
return null // non resolvable anonymous parties return null // non resolvable anonymous parties
} }
@ -27,7 +34,8 @@ class AbstractPartyToX500NameAsStringConverter(identitySvc: () -> IdentityServic
override fun convertToEntityAttribute(dbData: String?): AbstractParty? { override fun convertToEntityAttribute(dbData: String?): AbstractParty? {
dbData?.let { dbData?.let {
val party = identityService.partyFromX500Name(X500Name(dbData)) val party = identityService.partyFromX500Name(X500Name(dbData))
return party as AbstractParty if (party != null) return party
else log.warn ("Identity service unable to resolve X500name: $dbData")
} }
return null // non resolvable anonymous parties are stored as nulls return null // non resolvable anonymous parties are stored as nulls
} }

View File

@ -44,11 +44,14 @@ class ContractUpgradeFlowTest {
@Before @Before
fun setup() { fun setup() {
mockNet = MockNetwork() mockNet = MockNetwork()
val nodes = mockNet.createSomeNodes() val nodes = mockNet.createSomeNodes(notaryKeyPair = null) // prevent generation of notary override
a = nodes.partyNodes[0] a = nodes.partyNodes[0]
b = nodes.partyNodes[1] b = nodes.partyNodes[1]
notary = nodes.notaryNode.info.notaryIdentity notary = nodes.notaryNode.info.notaryIdentity
mockNet.runNetwork()
val nodeIdentity = nodes.notaryNode.info.legalIdentitiesAndCerts.single { it.party == nodes.notaryNode.info.notaryIdentity }
a.services.identityService.registerIdentity(nodeIdentity)
b.services.identityService.registerIdentity(nodeIdentity)
} }
@After @After

View File

@ -12,6 +12,7 @@ import net.corda.core.flows.FlowLogic
import net.corda.core.flows.InitiatedBy import net.corda.core.flows.InitiatedBy
import net.corda.core.flows.InitiatingFlow import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.* import net.corda.core.flows.*
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import net.corda.core.node.services.vault.QueryCriteria import net.corda.core.node.services.vault.QueryCriteria
@ -42,8 +43,8 @@ private fun gatherOurInputs(serviceHub: ServiceHub,
val ourParties = ourKeys.map { serviceHub.identityService.partyFromKey(it) ?: throw IllegalStateException("Unable to resolve party from key") } val ourParties = ourKeys.map { serviceHub.identityService.partyFromKey(it) ?: throw IllegalStateException("Unable to resolve party from key") }
val fungibleCriteria = QueryCriteria.FungibleAssetQueryCriteria(owner = ourParties) val fungibleCriteria = QueryCriteria.FungibleAssetQueryCriteria(owner = ourParties)
val notaryName = if (notary != null) notary.name else serviceHub.networkMapCache.getAnyNotary()!!.name val notaries = notary ?: serviceHub.networkMapCache.getAnyNotary()
val vaultCriteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(notaryName = listOf(notaryName)) val vaultCriteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(notary = listOf(notaries as AbstractParty))
val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.equal(amountRequired.token.product.currencyCode) } val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.equal(amountRequired.token.product.currencyCode) }
val cashCriteria = QueryCriteria.VaultCustomQueryCriteria(logicalExpression) val cashCriteria = QueryCriteria.VaultCustomQueryCriteria(logicalExpression)

View File

@ -10,6 +10,7 @@ import net.corda.core.crypto.testing.NULL_PARTY
import net.corda.core.crypto.toBase58String import net.corda.core.crypto.toBase58String
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.Emoji import net.corda.core.internal.Emoji
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import net.corda.core.node.services.StatesNotAvailableException import net.corda.core.node.services.StatesNotAvailableException
@ -98,7 +99,7 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
override fun generateMappedObject(schema: MappedSchema): PersistentState { override fun generateMappedObject(schema: MappedSchema): PersistentState {
return when (schema) { return when (schema) {
is CashSchemaV1 -> CashSchemaV1.PersistentCashState( is CashSchemaV1 -> CashSchemaV1.PersistentCashState(
owner = this.owner.owningKey.toBase58String(), owner = this.owner,
pennies = this.amount.quantity, pennies = this.amount.quantity,
currency = this.amount.token.product.currencyCode, currency = this.amount.token.product.currencyCode,
issuerParty = this.amount.token.issuer.party.owningKey.toBase58String(), issuerParty = this.amount.token.issuer.party.owningKey.toBase58String(),
@ -323,7 +324,7 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
AND (vs.lock_id = '$lockId' OR vs.lock_id is null) AND (vs.lock_id = '$lockId' OR vs.lock_id is null)
""" + """ +
(if (notary != null) (if (notary != null)
" AND vs.notary_key = '${notary.owningKey.toBase58String()}'" else "") + " AND vs.notary_name = '${notary.name}'" else "") +
(if (onlyFromIssuerParties.isNotEmpty()) (if (onlyFromIssuerParties.isNotEmpty())
" AND ccs.issuer_key IN ($issuerKeysStr)" else "") + " AND ccs.issuer_key IN ($issuerKeysStr)" else "") +
(if (withIssuerRefs.isNotEmpty()) (if (withIssuerRefs.isNotEmpty())

View File

@ -1,5 +1,6 @@
package net.corda.schemas package net.corda.schemas
import net.corda.core.identity.AbstractParty
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState import net.corda.core.schemas.PersistentState
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
@ -21,8 +22,9 @@ object CashSchemaV1 : MappedSchema(schemaFamily = CashSchema.javaClass, version
indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"), indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"),
Index(name = "pennies_idx", columnList = "pennies"))) Index(name = "pennies_idx", columnList = "pennies")))
class PersistentCashState( class PersistentCashState(
@Column(name = "owner_key") /** X500Name of owner party **/
var owner: String, @Column(name = "owner_name")
var owner: AbstractParty,
@Column(name = "pennies") @Column(name = "pennies")
var pennies: Long, var pennies: Long,

View File

@ -54,7 +54,7 @@ class DummyFungibleContract : OnLedgerAsset<Currency, DummyFungibleContract.Comm
issuerRef = this.amount.token.issuer.reference.bytes issuerRef = this.amount.token.issuer.reference.bytes
) )
is SampleCashSchemaV2 -> SampleCashSchemaV2.PersistentCashState( is SampleCashSchemaV2 -> SampleCashSchemaV2.PersistentCashState(
_participants = this.participants.toSet(), _participants = this.participants.toMutableSet(),
_owner = this.owner, _owner = this.owner,
_quantity = this.amount.quantity, _quantity = this.amount.quantity,
currency = this.amount.token.product.currencyCode, currency = this.amount.token.product.currencyCode,
@ -62,12 +62,12 @@ class DummyFungibleContract : OnLedgerAsset<Currency, DummyFungibleContract.Comm
_issuerRef = this.amount.token.issuer.reference.bytes _issuerRef = this.amount.token.issuer.reference.bytes
) )
is SampleCashSchemaV3 -> SampleCashSchemaV3.PersistentCashState( is SampleCashSchemaV3 -> SampleCashSchemaV3.PersistentCashState(
_participants = this.participants.toSet(), participants = this.participants.toMutableSet(),
_owner = this.owner, owner = this.owner,
_quantity = this.amount.quantity, pennies = this.amount.quantity,
_currency = this.amount.token.product.currencyCode, currency = this.amount.token.product.currencyCode,
_issuerParty = this.amount.token.issuer.party, issuer = this.amount.token.issuer.party,
_issuerRef = this.amount.token.issuer.reference.bytes issuerRef = this.amount.token.issuer.reference.bytes
) )
else -> throw IllegalArgumentException("Unrecognised schema $schema") else -> throw IllegalArgumentException("Unrecognised schema $schema")
} }

View File

@ -13,7 +13,7 @@ import javax.persistence.Table
* [VaultFungibleState] abstract schema * [VaultFungibleState] abstract schema
*/ */
object SampleCashSchemaV2 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 2, object SampleCashSchemaV2 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 2,
mappedTypes = listOf(PersistentCashState::class.java, CommonSchemaV1.Party::class.java)) { mappedTypes = listOf(PersistentCashState::class.java)) {
@Entity @Entity
@Table(name = "cash_states_v2", @Table(name = "cash_states_v2",
indexes = arrayOf(Index(name = "ccy_code_idx2", columnList = "ccy_code"))) indexes = arrayOf(Index(name = "ccy_code_idx2", columnList = "ccy_code")))
@ -33,5 +33,5 @@ object SampleCashSchemaV2 : MappedSchema(schemaFamily = CashSchema.javaClass, ve
val _issuerParty: AbstractParty, val _issuerParty: AbstractParty,
@Transient @Transient
val _issuerRef: ByteArray val _issuerRef: ByteArray
) : CommonSchemaV1.FungibleState(_participants, _owner, _quantity, _issuerParty, _issuerRef) ) : CommonSchemaV1.FungibleState(_participants.toMutableSet(), _owner, _quantity, _issuerParty, _issuerRef)
} }

View File

@ -11,16 +11,19 @@ import javax.persistence.*
* at the time of writing. * at the time of writing.
*/ */
object SampleCashSchemaV3 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 3, object SampleCashSchemaV3 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 3,
mappedTypes = listOf(PersistentCashState::class.java, CommonSchemaV1.Party::class.java)) { mappedTypes = listOf(PersistentCashState::class.java)) {
@Entity @Entity
@Table(name = "cash_states_v3") @Table(name = "cash_states_v3")
class PersistentCashState( class PersistentCashState(
/** [ContractState] attributes */ /** [ContractState] attributes */
@OneToMany(cascade = arrayOf(CascadeType.ALL))
var participants: Set<CommonSchemaV1.Party>,
@OneToOne(cascade = arrayOf(CascadeType.ALL)) /** X500Name of participant parties **/
var owner: CommonSchemaV1.Party, @ElementCollection
var participants: MutableSet<AbstractParty>? = null,
/** X500Name of owner party **/
@Column(name = "owner_name")
var owner: AbstractParty,
@Column(name = "pennies") @Column(name = "pennies")
var pennies: Long, var pennies: Long,
@ -28,18 +31,11 @@ object SampleCashSchemaV3 : MappedSchema(schemaFamily = CashSchema.javaClass, ve
@Column(name = "ccy_code", length = 3) @Column(name = "ccy_code", length = 3)
var currency: String, var currency: String,
@OneToOne(cascade = arrayOf(CascadeType.ALL)) /** X500Name of issuer party **/
var issuerParty: CommonSchemaV1.Party, @Column(name = "issuer_name")
var issuer: AbstractParty,
@Column(name = "issuer_ref") @Column(name = "issuer_ref")
var issuerRef: ByteArray var issuerRef: ByteArray
) : PersistentState() { ) : PersistentState()
constructor(_participants: Set<AbstractParty>, _owner: AbstractParty, _quantity: Long, _currency: String, _issuerParty: AbstractParty, _issuerRef: ByteArray)
: this(participants = _participants.map { CommonSchemaV1.Party(it) }.toSet(),
owner = CommonSchemaV1.Party(_owner),
pennies = _quantity,
currency = _currency,
issuerParty = CommonSchemaV1.Party(_issuerParty),
issuerRef = _issuerRef)
}
} }

View File

@ -14,7 +14,7 @@ import javax.persistence.Table
* [VaultFungibleState] abstract schema * [VaultFungibleState] abstract schema
*/ */
object SampleCommercialPaperSchemaV2 : MappedSchema(schemaFamily = CommercialPaperSchema.javaClass, version = 1, object SampleCommercialPaperSchemaV2 : MappedSchema(schemaFamily = CommercialPaperSchema.javaClass, version = 1,
mappedTypes = listOf(PersistentCommercialPaperState::class.java, CommonSchemaV1.Party::class.java)) { mappedTypes = listOf(PersistentCommercialPaperState::class.java)) {
@Entity @Entity
@Table(name = "cp_states_v2", @Table(name = "cp_states_v2",
indexes = arrayOf(Index(name = "ccy_code_index2", columnList = "ccy_code"), indexes = arrayOf(Index(name = "ccy_code_index2", columnList = "ccy_code"),
@ -44,5 +44,5 @@ object SampleCommercialPaperSchemaV2 : MappedSchema(schemaFamily = CommercialPap
val _issuerParty: AbstractParty, val _issuerParty: AbstractParty,
@Transient @Transient
val _issuerRef: ByteArray val _issuerRef: ByteArray
) : CommonSchemaV1.FungibleState(_participants, _owner, _quantity, _issuerParty, _issuerRef) ) : CommonSchemaV1.FungibleState(_participants.toMutableSet(), _owner, _quantity, _issuerParty, _issuerRef)
} }

View File

@ -41,9 +41,6 @@ object VaultSchema {
@get:Column(name = "notary_name") @get:Column(name = "notary_name")
var notaryName: String var notaryName: String
@get:Column(name = "notary_key", length = 65535) // TODO What is the upper limit on size of CompositeKey?
var notaryKey: String
/** references a concrete ContractState that is [QueryableState] and has a [MappedSchema] */ /** references a concrete ContractState that is [QueryableState] and has a [MappedSchema] */
@get:Column(name = "contract_state_class_name") @get:Column(name = "contract_state_class_name")
var contractStateClassName: String var contractStateClassName: String

View File

@ -314,7 +314,6 @@ class VaultSchemaTest : TestDependencyInjectionBase() {
contractStateClassName = state.data.javaClass.name contractStateClassName = state.data.javaClass.name
contractState = state.serialize().bytes contractState = state.serialize().bytes
notaryName = state.notary.name.toString() notaryName = state.notary.name.toString()
notaryKey = state.notary.owningKey.toBase58String()
recordedTime = Instant.now() recordedTime = Instant.now()
} }
} }
@ -655,15 +654,12 @@ class VaultSchemaTest : TestDependencyInjectionBase() {
@Test @Test
fun insertWithBigCompositeKey() { fun insertWithBigCompositeKey() {
val keys = (1..314).map { generateKeyPair().public }
val bigNotaryKey = CompositeKey.Builder().addKeys(keys).build()
val vaultStEntity = VaultStatesEntity().apply { val vaultStEntity = VaultStatesEntity().apply {
txId = SecureHash.randomSHA256().toString() txId = SecureHash.randomSHA256().toString()
index = 314 index = 314
stateStatus = Vault.StateStatus.UNCONSUMED stateStatus = Vault.StateStatus.UNCONSUMED
contractStateClassName = VaultNoopContract.VaultNoopState::class.java.name contractStateClassName = VaultNoopContract.VaultNoopState::class.java.name
notaryName = "Huge distributed notary" notaryName = "Huge distributed notary"
notaryKey = bigNotaryKey.toBase58String()
recordedTime = Instant.now() recordedTime = Instant.now()
} }
data.insert(vaultStEntity) data.insert(vaultStEntity)

View File

@ -7,14 +7,12 @@ import net.corda.core.node.services.Vault
import net.corda.core.node.services.VaultQueryException import net.corda.core.node.services.VaultQueryException
import net.corda.core.node.services.vault.* import net.corda.core.node.services.vault.*
import net.corda.core.node.services.vault.QueryCriteria.CommonQueryCriteria import net.corda.core.node.services.vault.QueryCriteria.CommonQueryCriteria
import net.corda.core.schemas.CommonSchemaV1
import net.corda.core.schemas.PersistentState import net.corda.core.schemas.PersistentState
import net.corda.core.schemas.PersistentStateRef import net.corda.core.schemas.PersistentStateRef
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.toHexString import net.corda.core.utilities.toHexString
import net.corda.core.utilities.trace import net.corda.core.utilities.trace
import org.bouncycastle.asn1.x500.X500Name
import java.util.* import java.util.*
import javax.persistence.Tuple import javax.persistence.Tuple
import javax.persistence.criteria.* import javax.persistence.criteria.*
@ -68,9 +66,8 @@ class HibernateQueryCriteriaParser(val contractType: Class<out ContractState>,
} }
// notary names // notary names
criteria.notaryName?.let { criteria.notary?.let {
val notaryNames = (criteria.notaryName as List<X500Name>).map { it.toString() } predicateSet.add(criteriaBuilder.and(vaultStates.get<AbstractParty>("notary").`in`(criteria.notary)))
predicateSet.add(criteriaBuilder.and(vaultStates.get<String>("notaryName").`in`(notaryNames)))
} }
// state references // state references
@ -243,10 +240,8 @@ class HibernateQueryCriteriaParser(val contractType: Class<out ContractState>,
// owner // owner
criteria.owner?.let { criteria.owner?.let {
val ownerKeys = criteria.owner as List<AbstractParty> val owners = criteria.owner as List<AbstractParty>
val joinFungibleStateToParty = vaultFungibleStates.join<VaultSchemaV1.VaultFungibleStates, CommonSchemaV1.Party>("issuerParty") predicateSet.add(criteriaBuilder.and(vaultFungibleStates.get<AbstractParty>("owner").`in`(owners)))
val owners = ownerKeys.map { it.nameOrNull()?.toString() ?: it.toString()}
predicateSet.add(criteriaBuilder.and(joinFungibleStateToParty.get<CommonSchemaV1.Party>("name").`in`(owners)))
} }
// quantity // quantity
@ -255,11 +250,9 @@ class HibernateQueryCriteriaParser(val contractType: Class<out ContractState>,
} }
// issuer party // issuer party
criteria.issuerPartyName?.let { criteria.issuer?.let {
val issuerParties = criteria.issuerPartyName as List<AbstractParty> val issuerParties = criteria.issuer as List<AbstractParty>
val joinFungibleStateToParty = vaultFungibleStates.join<VaultSchemaV1.VaultFungibleStates, CommonSchemaV1.Party>("issuerParty") predicateSet.add(criteriaBuilder.and(vaultFungibleStates.get<AbstractParty>("issuer").`in`(issuerParties)))
val issuerPartyNames = issuerParties.map { it.nameOrNull().toString() }
predicateSet.add(criteriaBuilder.and(joinFungibleStateToParty.get<CommonSchemaV1.Party>("name").`in`(issuerPartyNames)))
} }
// issuer reference // issuer reference
@ -271,9 +264,8 @@ class HibernateQueryCriteriaParser(val contractType: Class<out ContractState>,
// participants // participants
criteria.participants?.let { criteria.participants?.let {
val participants = criteria.participants as List<AbstractParty> val participants = criteria.participants as List<AbstractParty>
val joinFungibleStateToParty = vaultFungibleStates.join<VaultSchemaV1.VaultFungibleStates, CommonSchemaV1.Party>("participants") val joinLinearStateToParty = vaultFungibleStates.joinSet<VaultSchemaV1.VaultLinearStates, AbstractParty>("participants")
val participantKeys = participants.map { it.nameOrNull().toString() } predicateSet.add(criteriaBuilder.and(joinLinearStateToParty.`in`(participants)))
predicateSet.add(criteriaBuilder.and(joinFungibleStateToParty.get<CommonSchemaV1.Party>("name").`in`(participantKeys)))
criteriaQuery.distinct(true) criteriaQuery.distinct(true)
} }
return predicateSet return predicateSet
@ -310,9 +302,8 @@ class HibernateQueryCriteriaParser(val contractType: Class<out ContractState>,
// deal participants // deal participants
criteria.participants?.let { criteria.participants?.let {
val participants = criteria.participants as List<AbstractParty> val participants = criteria.participants as List<AbstractParty>
val joinLinearStateToParty = vaultLinearStates.join<VaultSchemaV1.VaultLinearStates, CommonSchemaV1.Party>("participants") val joinLinearStateToParty = vaultLinearStates.joinSet<VaultSchemaV1.VaultLinearStates, AbstractParty>("participants")
val participantKeys = participants.map { it.nameOrNull().toString() } predicateSet.add(criteriaBuilder.and(joinLinearStateToParty.`in`(participants)))
predicateSet.add(criteriaBuilder.and(joinLinearStateToParty.get<CommonSchemaV1.Party>("name").`in`(participantKeys)))
criteriaQuery.distinct(true) criteriaQuery.distinct(true)
} }
return predicateSet return predicateSet

View File

@ -119,7 +119,14 @@ class HibernateVaultQueryImpl(hibernateConfig: HibernateConfiguration,
val vaultState = result[0] as VaultSchemaV1.VaultStates val vaultState = result[0] as VaultSchemaV1.VaultStates
val stateRef = StateRef(SecureHash.parse(vaultState.stateRef!!.txId!!), vaultState.stateRef!!.index!!) val stateRef = StateRef(SecureHash.parse(vaultState.stateRef!!.txId!!), vaultState.stateRef!!.index!!)
val state = vaultState.contractState.deserialize<TransactionState<T>>(context = STORAGE_CONTEXT) val state = vaultState.contractState.deserialize<TransactionState<T>>(context = STORAGE_CONTEXT)
statesMeta.add(Vault.StateMetadata(stateRef, vaultState.contractStateClassName, vaultState.recordedTime, vaultState.consumedTime, vaultState.stateStatus, vaultState.notaryName, vaultState.notaryKey, vaultState.lockId, vaultState.lockUpdateTime)) statesMeta.add(Vault.StateMetadata(stateRef,
vaultState.contractStateClassName,
vaultState.recordedTime,
vaultState.consumedTime,
vaultState.stateStatus,
vaultState.notary,
vaultState.lockId,
vaultState.lockUpdateTime))
statesAndRefs.add(StateAndRef(state, stateRef)) statesAndRefs.add(StateAndRef(state, stateRef))
} }
else { else {

View File

@ -98,7 +98,6 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
contractStateClassName = it.value.state.data.javaClass.name contractStateClassName = it.value.state.data.javaClass.name
contractState = it.value.state.serialize(context = STORAGE_CONTEXT).bytes contractState = it.value.state.serialize(context = STORAGE_CONTEXT).bytes
notaryName = it.value.state.notary.name.toString() notaryName = it.value.state.notary.name.toString()
notaryKey = it.value.state.notary.owningKey.toBase58String()
recordedTime = services.clock.instant() recordedTime = services.clock.instant()
} }
insert(state) insert(state)

View File

@ -1,9 +1,9 @@
package net.corda.node.services.vault package net.corda.node.services.vault
import net.corda.core.contracts.ContractState
import net.corda.core.contracts.UniqueIdentifier import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
import net.corda.core.schemas.CommonSchemaV1
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState import net.corda.core.schemas.PersistentState
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
@ -22,17 +22,14 @@ object VaultSchema
*/ */
@CordaSerializable @CordaSerializable
object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, version = 1, object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, version = 1,
mappedTypes = listOf(VaultStates::class.java, VaultLinearStates::class.java, VaultFungibleStates::class.java, CommonSchemaV1.Party::class.java)) { mappedTypes = listOf(VaultStates::class.java, VaultLinearStates::class.java, VaultFungibleStates::class.java)) {
@Entity @Entity
@Table(name = "vault_states", @Table(name = "vault_states",
indexes = arrayOf(Index(name = "state_status_idx", columnList = "state_status"))) indexes = arrayOf(Index(name = "state_status_idx", columnList = "state_status")))
class VaultStates( class VaultStates(
/** refers to the notary a state is attached to */ /** refers to the X500Name of the notary a state is attached to */
@Column(name = "notary_name") @Column(name = "notary_name")
var notaryName: String, var notary: AbstractParty,
@Column(name = "notary_key", length = 65535) // TODO What is the upper limit on size of CompositeKey?
var notaryKey: String,
/** references a concrete ContractState that is [QueryableState] and has a [MappedSchema] */ /** references a concrete ContractState that is [QueryableState] and has a [MappedSchema] */
@Column(name = "contract_state_class_name") @Column(name = "contract_state_class_name")
@ -71,8 +68,13 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
Index(name = "uuid_index", columnList = "uuid"))) Index(name = "uuid_index", columnList = "uuid")))
class VaultLinearStates( class VaultLinearStates(
/** [ContractState] attributes */ /** [ContractState] attributes */
@OneToMany(cascade = arrayOf(CascadeType.ALL))
var participants: Set<CommonSchemaV1.Party>, /** X500Name of participant parties **/
@ElementCollection
@Column(name = "participants")
var participants: MutableSet<AbstractParty>? = 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] * Represents a [LinearState] [UniqueIdentifier]
@ -86,18 +88,23 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
constructor(uid: UniqueIdentifier, _participants: List<AbstractParty>) : constructor(uid: UniqueIdentifier, _participants: List<AbstractParty>) :
this(externalId = uid.externalId, this(externalId = uid.externalId,
uuid = uid.id, uuid = uid.id,
participants = _participants.map{ CommonSchemaV1.Party(it) }.toSet() ) participants = _participants.toMutableSet())
} }
@Entity @Entity
@Table(name = "vault_fungible_states") @Table(name = "vault_fungible_states")
class VaultFungibleStates( class VaultFungibleStates(
/** [ContractState] attributes */ /** [ContractState] attributes */
@OneToMany(cascade = arrayOf(CascadeType.ALL))
var participants: Set<CommonSchemaV1.Party>, /** X500Name of participant parties **/
@ElementCollection
@Column(name = "participants")
var participants: MutableSet<AbstractParty>? = null,
/** [OwnableState] attributes */ /** [OwnableState] attributes */
@Column(name = "owner_id")
/** X500Name of owner party **/
@Column(name = "owner_name")
var owner: AbstractParty, var owner: AbstractParty,
/** [FungibleAsset] attributes /** [FungibleAsset] attributes
@ -111,8 +118,10 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
var quantity: Long, var quantity: Long,
/** Issuer attributes */ /** Issuer attributes */
@OneToOne(cascade = arrayOf(CascadeType.ALL))
var issuerParty: CommonSchemaV1.Party, /** X500Name of issuer party **/
@Column(name = "issuer_name")
var issuer: AbstractParty,
@Column(name = "issuer_reference") @Column(name = "issuer_reference")
var issuerRef: ByteArray var issuerRef: ByteArray
@ -120,8 +129,8 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
constructor(_owner: AbstractParty, _quantity: Long, _issuerParty: AbstractParty, _issuerRef: OpaqueBytes, _participants: List<AbstractParty>) : constructor(_owner: AbstractParty, _quantity: Long, _issuerParty: AbstractParty, _issuerRef: OpaqueBytes, _participants: List<AbstractParty>) :
this(owner = _owner, this(owner = _owner,
quantity = _quantity, quantity = _quantity,
issuerParty = CommonSchemaV1.Party(_issuerParty), issuer = _issuerParty,
issuerRef = _issuerRef.bytes, issuerRef = _issuerRef.bytes,
participants = _participants.map { CommonSchemaV1.Party(it) }.toSet()) participants = _participants.toMutableSet())
} }
} }

View File

@ -8,9 +8,7 @@ import net.corda.core.contracts.*;
import net.corda.core.crypto.EncodingUtils; import net.corda.core.crypto.EncodingUtils;
import net.corda.core.identity.AbstractParty; import net.corda.core.identity.AbstractParty;
import net.corda.core.messaging.DataFeed; import net.corda.core.messaging.DataFeed;
import net.corda.core.node.services.Vault; import net.corda.core.node.services.*;
import net.corda.core.node.services.VaultQueryException;
import net.corda.core.node.services.VaultQueryService;
import net.corda.core.node.services.vault.*; import net.corda.core.node.services.vault.*;
import net.corda.core.node.services.vault.QueryCriteria.LinearStateQueryCriteria; import net.corda.core.node.services.vault.QueryCriteria.LinearStateQueryCriteria;
import net.corda.core.node.services.vault.QueryCriteria.VaultCustomQueryCriteria; import net.corda.core.node.services.vault.QueryCriteria.VaultCustomQueryCriteria;
@ -44,6 +42,7 @@ import static net.corda.core.utilities.ByteArrays.toHexString;
import static net.corda.testing.CoreTestUtils.*; import static net.corda.testing.CoreTestUtils.*;
import static net.corda.testing.TestConstants.*; import static net.corda.testing.TestConstants.*;
import static net.corda.testing.node.MockServicesKt.makeTestDatabaseAndMockServices; import static net.corda.testing.node.MockServicesKt.makeTestDatabaseAndMockServices;
import static net.corda.testing.node.MockServicesKt.makeTestIdentityService;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
public class VaultQueryJavaTests extends TestDependencyInjectionBase { public class VaultQueryJavaTests extends TestDependencyInjectionBase {
@ -58,7 +57,9 @@ public class VaultQueryJavaTests extends TestDependencyInjectionBase {
ArrayList<KeyPair> keys = new ArrayList<>(); ArrayList<KeyPair> keys = new ArrayList<>();
keys.add(getMEGA_CORP_KEY()); keys.add(getMEGA_CORP_KEY());
keys.add(getDUMMY_NOTARY_KEY()); keys.add(getDUMMY_NOTARY_KEY());
Pair<CordaPersistence, MockServices> databaseAndServices = makeTestDatabaseAndMockServices(Collections.EMPTY_SET, keys);
IdentityService identitySvc = makeTestIdentityService();
Pair<CordaPersistence, MockServices> databaseAndServices = makeTestDatabaseAndMockServices(Collections.EMPTY_SET, keys, () -> identitySvc);
issuerServices = new MockServices(getDUMMY_CASH_ISSUER_KEY(), getBOC_KEY()); issuerServices = new MockServices(getDUMMY_CASH_ISSUER_KEY(), getBOC_KEY());
database = databaseAndServices.getFirst(); database = databaseAndServices.getFirst();
services = databaseAndServices.getSecond(); services = databaseAndServices.getSecond();

View File

@ -641,9 +641,8 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
// search predicate // search predicate
val cashStatesSchema = criteriaQuery.from(SampleCashSchemaV3.PersistentCashState::class.java) val cashStatesSchema = criteriaQuery.from(SampleCashSchemaV3.PersistentCashState::class.java)
val joinCashToParty = cashStatesSchema.join<SampleCashSchemaV3.PersistentCashState, CommonSchemaV1.Party>("owner") val queryOwner = BOB.name.toString()
val queryOwnerKey = BOB_PUBKEY.toBase58String() criteriaQuery.where(criteriaBuilder.equal(cashStatesSchema.get<String>("owner"), queryOwner))
criteriaQuery.where(criteriaBuilder.equal(joinCashToParty.get<CommonSchemaV1.Party>("key"), queryOwnerKey))
val joinVaultStatesToCash = criteriaBuilder.equal(vaultStates.get<PersistentStateRef>("stateRef"), cashStatesSchema.get<PersistentStateRef>("stateRef")) val joinVaultStatesToCash = criteriaBuilder.equal(vaultStates.get<PersistentStateRef>("stateRef"), cashStatesSchema.get<PersistentStateRef>("stateRef"))
criteriaQuery.where(joinVaultStatesToCash) criteriaQuery.where(joinVaultStatesToCash)
@ -726,9 +725,9 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
// search predicate // search predicate
val cashStatesSchema = criteriaQuery.from(SampleCashSchemaV3.PersistentCashState::class.java) val cashStatesSchema = criteriaQuery.from(SampleCashSchemaV3.PersistentCashState::class.java)
val joinCashToParty = cashStatesSchema.join<SampleCashSchemaV3.PersistentCashState, CommonSchemaV1.Party>("participants") val queryParticipants = firstCashState.state.data.participants.map { it.nameOrNull().toString() }
val queryParticipantKeys = firstCashState.state.data.participants.map { it.owningKey.toBase58String() } val joinCashStateToParty = cashStatesSchema.joinSet<SampleCashSchemaV3.PersistentCashState, String>("participants")
criteriaQuery.where(criteriaBuilder.equal(joinCashToParty.get<CommonSchemaV1.Party>("key"), queryParticipantKeys)) criteriaQuery.where(criteriaBuilder.and(joinCashStateToParty.`in`(queryParticipants)))
val joinVaultStatesToCash = criteriaBuilder.equal(vaultStates.get<PersistentStateRef>("stateRef"), cashStatesSchema.get<PersistentStateRef>("stateRef")) val joinVaultStatesToCash = criteriaBuilder.equal(vaultStates.get<PersistentStateRef>("stateRef"), cashStatesSchema.get<PersistentStateRef>("stateRef"))
criteriaQuery.where(joinVaultStatesToCash) criteriaQuery.where(joinVaultStatesToCash)

View File

@ -174,7 +174,6 @@ class RequeryConfigurationTest : TestDependencyInjectionBase() {
contractStateClassName = DummyContract.SingleOwnerState::class.java.name contractStateClassName = DummyContract.SingleOwnerState::class.java.name
contractState = DummyContract.SingleOwnerState(owner = AnonymousParty(MEGA_CORP_PUBKEY)).serialize().bytes contractState = DummyContract.SingleOwnerState(owner = AnonymousParty(MEGA_CORP_PUBKEY)).serialize().bytes
notaryName = txn.tx.notary!!.name.toString() notaryName = txn.tx.notary!!.name.toString()
notaryKey = txn.tx.notary!!.owningKey.toBase58String()
recordedTime = Instant.now() recordedTime = Instant.now()
} }
return state return state

View File

@ -69,11 +69,11 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() {
lockId: UUID = UUID.randomUUID(), lockId: UUID = UUID.randomUUID(),
withIssuerRefs: Set<OpaqueBytes>? = null): List<StateAndRef<Cash.State>> { withIssuerRefs: Set<OpaqueBytes>? = null): List<StateAndRef<Cash.State>> {
val notaryName = if (notary != null) listOf(notary.name) else null val notaries = if (notary != null) listOf(notary) else null
var baseCriteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(notaryName = notaryName) var baseCriteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(notary = notaries)
if (onlyFromIssuerParties != null || withIssuerRefs != null) { if (onlyFromIssuerParties != null || withIssuerRefs != null) {
baseCriteria = baseCriteria.and(QueryCriteria.FungibleAssetQueryCriteria( baseCriteria = baseCriteria.and(QueryCriteria.FungibleAssetQueryCriteria(
issuerPartyName = onlyFromIssuerParties?.toList(), issuer = onlyFromIssuerParties?.toList(),
issuerRef = withIssuerRefs?.toList())) issuerRef = withIssuerRefs?.toList()))
} }

View File

@ -11,6 +11,7 @@ import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.entropyToKeyPair import net.corda.core.crypto.entropyToKeyPair
import net.corda.core.crypto.toBase58String import net.corda.core.crypto.toBase58String
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.services.* import net.corda.core.node.services.*
import net.corda.core.node.services.vault.* import net.corda.core.node.services.vault.*
import net.corda.core.node.services.vault.QueryCriteria.* import net.corda.core.node.services.vault.QueryCriteria.*
@ -50,11 +51,20 @@ class VaultQueryTests : TestDependencyInjectionBase() {
lateinit var notaryServices: MockServices lateinit var notaryServices: MockServices
val vaultSvc: VaultService get() = services.vaultService val vaultSvc: VaultService get() = services.vaultService
val vaultQuerySvc: VaultQueryService get() = services.vaultQueryService val vaultQuerySvc: VaultQueryService get() = services.vaultQueryService
val identitySvc: IdentityService = makeTestIdentityService()
lateinit var database: CordaPersistence lateinit var database: CordaPersistence
// test cash notary
val CASH_NOTARY_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(21)) }
val CASH_NOTARY: Party get() = Party(X500Name("CN=Cash Notary Service,O=R3,OU=corda,L=Zurich,C=CH"), CASH_NOTARY_KEY.public)
val CASH_NOTARY_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(CASH_NOTARY.nameOrNull()!!, CASH_NOTARY_KEY.public)
@Before @Before
fun setUp() { fun setUp() {
val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(MEGA_CORP_KEY, DUMMY_NOTARY_KEY)) // register additional identities
identitySvc.verifyAndRegisterIdentity(CASH_NOTARY_IDENTITY)
identitySvc.verifyAndRegisterIdentity(BOC_IDENTITY)
val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(MEGA_CORP_KEY, DUMMY_NOTARY_KEY), identitySvc = { identitySvc })
database = databaseAndServices.first database = databaseAndServices.first
services = databaseAndServices.second services = databaseAndServices.second
notaryServices = MockServices(DUMMY_NOTARY_KEY, DUMMY_CASH_ISSUER_KEY, BOC_KEY, MEGA_CORP_KEY) notaryServices = MockServices(DUMMY_NOTARY_KEY, DUMMY_CASH_ISSUER_KEY, BOC_KEY, MEGA_CORP_KEY)
@ -71,7 +81,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Ignore @Ignore
@Test @Test
fun createPersistentTestDb() { fun createPersistentTestDb() {
val database = configureDatabase(makePersistentDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService) val database = configureDatabase(makePersistentDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = { identitySvc })
setUpDb(database, 5000) setUpDb(database, 5000)
@ -396,9 +406,6 @@ class VaultQueryTests : TestDependencyInjectionBase() {
} }
} }
val CASH_NOTARY_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(21)) }
val CASH_NOTARY: Party get() = Party(X500Name("CN=Cash Notary Service,O=R3,OU=corda,L=Zurich,C=CH"), CASH_NOTARY_KEY.public)
@Test @Test
fun `unconsumed states by notary`() { fun `unconsumed states by notary`() {
database.transaction { database.transaction {
@ -408,7 +415,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
services.fillWithSomeTestDeals(listOf("123", "456", "789")) services.fillWithSomeTestDeals(listOf("123", "456", "789"))
// DOCSTART VaultQueryExample4 // DOCSTART VaultQueryExample4
val criteria = VaultQueryCriteria(notaryName = listOf(CASH_NOTARY.name)) val criteria = VaultQueryCriteria(notary = listOf(CASH_NOTARY))
val results = vaultQuerySvc.queryBy<ContractState>(criteria) val results = vaultQuerySvc.queryBy<ContractState>(criteria)
// DOCEND VaultQueryExample4 // DOCEND VaultQueryExample4
assertThat(results.states).hasSize(3) assertThat(results.states).hasSize(3)
@ -418,6 +425,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test @Test
fun `unconsumed linear states for single participant`() { fun `unconsumed linear states for single participant`() {
database.transaction { database.transaction {
identitySvc.verifyAndRegisterIdentity(BIG_CORP_IDENTITY)
services.fillWithSomeTestLinearStates(2, "TEST", participants = listOf(MEGA_CORP, MINI_CORP)) services.fillWithSomeTestLinearStates(2, "TEST", participants = listOf(MEGA_CORP, MINI_CORP))
services.fillWithSomeTestDeals(listOf("456"), participants = listOf(MEGA_CORP, BIG_CORP)) services.fillWithSomeTestDeals(listOf("456"), participants = listOf(MEGA_CORP, BIG_CORP))
@ -433,13 +441,14 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test @Test
fun `unconsumed linear states for two participants`() { fun `unconsumed linear states for two participants`() {
database.transaction { database.transaction {
identitySvc.verifyAndRegisterIdentity(BIG_CORP_IDENTITY)
services.fillWithSomeTestLinearStates(2, "TEST", participants = listOf(MEGA_CORP, MINI_CORP)) services.fillWithSomeTestLinearStates(2, "TEST", participants = listOf(MEGA_CORP, MINI_CORP))
services.fillWithSomeTestDeals(listOf("456"), participants = listOf(MEGA_CORP, BIG_CORP)) services.fillWithSomeTestDeals(listOf("456"), participants = listOf(MEGA_CORP, BIG_CORP))
services.fillWithSomeTestDeals(listOf("123", "789"), participants = listOf(BIG_CORP)) services.fillWithSomeTestDeals(listOf("123", "789"), participants = listOf(MEGA_CORP))
// DOCSTART VaultQueryExample5 // DOCSTART VaultQueryExample5
val criteria = LinearStateQueryCriteria(participants = listOf(MEGA_CORP, MINI_CORP)) val criteria = LinearStateQueryCriteria(participants = listOf(BIG_CORP, MINI_CORP))
val results = vaultQuerySvc.queryBy<ContractState>(criteria) val results = vaultQuerySvc.queryBy<ContractState>(criteria)
// DOCEND VaultQueryExample5 // DOCEND VaultQueryExample5
@ -793,6 +802,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test @Test
fun `aggregate functions sum by issuer and currency and sort by aggregate sum`() { fun `aggregate functions sum by issuer and currency and sort by aggregate sum`() {
database.transaction { database.transaction {
identitySvc.verifyAndRegisterIdentity(BOC_IDENTITY)
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = DUMMY_CASH_ISSUER) services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = DUMMY_CASH_ISSUER)
services.fillWithSomeTestCash(200.DOLLARS, notaryServices, DUMMY_NOTARY, 2, 2, Random(0L), issuedBy = BOC.ref(1)) services.fillWithSomeTestCash(200.DOLLARS, notaryServices, DUMMY_NOTARY, 2, 2, Random(0L), issuedBy = BOC.ref(1))
@ -1026,6 +1036,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 100, 100, Random(0L)) services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 100, 100, Random(0L))
@Suppress("OVERFLOW_EXPECTED")
val pagingSpec = PageSpecification(DEFAULT_PAGE_NUM, MAX_PAGE_SIZE + 1) // overflow = -2147483648 val pagingSpec = PageSpecification(DEFAULT_PAGE_NUM, MAX_PAGE_SIZE + 1) // overflow = -2147483648
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL) val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
vaultQuerySvc.queryBy<ContractState>(criteria, paging = pagingSpec) vaultQuerySvc.queryBy<ContractState>(criteria, paging = pagingSpec)
@ -1375,7 +1386,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
database.transaction { database.transaction {
val parties = listOf(MEGA_CORP) val parties = listOf(MINI_CORP)
services.fillWithSomeTestLinearStates(2, "TEST") services.fillWithSomeTestLinearStates(2, "TEST")
services.fillWithSomeTestDeals(listOf("456"), parties) services.fillWithSomeTestDeals(listOf("456"), parties)
@ -1395,13 +1406,14 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test @Test
fun `unconsumed fungible assets for specific issuer party and refs`() { fun `unconsumed fungible assets for specific issuer party and refs`() {
database.transaction { database.transaction {
identitySvc.verifyAndRegisterIdentity(BOC_IDENTITY)
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (DUMMY_CASH_ISSUER)) services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (DUMMY_CASH_ISSUER))
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (BOC.ref(1)), ref = OpaqueBytes.of(1)) services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (BOC.ref(1)), ref = OpaqueBytes.of(1))
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (BOC.ref(2)), ref = OpaqueBytes.of(2)) services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (BOC.ref(2)), ref = OpaqueBytes.of(2))
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (BOC.ref(3)), ref = OpaqueBytes.of(3)) services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (BOC.ref(3)), ref = OpaqueBytes.of(3))
val criteria = FungibleAssetQueryCriteria(issuerPartyName = listOf(BOC), val criteria = FungibleAssetQueryCriteria(issuer = listOf(BOC),
issuerRef = listOf(BOC.ref(1).reference, BOC.ref(2).reference)) issuerRef = listOf(BOC.ref(1).reference, BOC.ref(2).reference))
val results = vaultQuerySvc.queryBy<FungibleAsset<*>>(criteria) val results = vaultQuerySvc.queryBy<FungibleAsset<*>>(criteria)
assertThat(results.states).hasSize(2) assertThat(results.states).hasSize(2)
@ -1424,11 +1436,12 @@ class VaultQueryTests : TestDependencyInjectionBase() {
val chfCashIssuerServices = MockServices(chfCashIssuerKey) val chfCashIssuerServices = MockServices(chfCashIssuerKey)
database.transaction { database.transaction {
services.fillWithSomeTestCash(100.POUNDS, gbpCashIssuerServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (gbpCashIssuer)) services.fillWithSomeTestCash(100.POUNDS, gbpCashIssuerServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (gbpCashIssuer))
services.fillWithSomeTestCash(100.DOLLARS, usdCashIssuerServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (usdCashIssuer)) services.fillWithSomeTestCash(100.DOLLARS, usdCashIssuerServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (usdCashIssuer))
services.fillWithSomeTestCash(100.SWISS_FRANCS, chfCashIssuerServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (chfCashIssuer)) services.fillWithSomeTestCash(100.SWISS_FRANCS, chfCashIssuerServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (chfCashIssuer))
val criteria = FungibleAssetQueryCriteria(issuerPartyName = listOf(gbpCashIssuer.party, usdCashIssuer.party)) val criteria = FungibleAssetQueryCriteria(issuer = listOf(gbpCashIssuer.party, usdCashIssuer.party))
val results = vaultQuerySvc.queryBy<FungibleAsset<*>>(criteria) val results = vaultQuerySvc.queryBy<FungibleAsset<*>>(criteria)
assertThat(results.states).hasSize(2) assertThat(results.states).hasSize(2)
} }
@ -1438,17 +1451,16 @@ class VaultQueryTests : TestDependencyInjectionBase() {
fun `unconsumed fungible assets by owner`() { fun `unconsumed fungible assets by owner`() {
database.transaction { database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 2, 2, Random(0L), issuedBy = BOC.ref(1)) services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = BOC.ref(1))
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L),
issuedBy = MEGA_CORP.ref(0), ownedBy = (MEGA_CORP)) issuedBy = MEGA_CORP.ref(0), ownedBy = (MINI_CORP))
val criteria = FungibleAssetQueryCriteria(owner = listOf(MEGA_CORP)) val criteria = FungibleAssetQueryCriteria(owner = listOf(MEGA_CORP))
val results = vaultQuerySvc.queryBy<FungibleAsset<*>>(criteria) val results = vaultQuerySvc.queryBy<FungibleAsset<*>>(criteria)
assertThat(results.states).hasSize(1) assertThat(results.states).hasSize(1) // can only be 1 owner of a node (MEGA_CORP in this MockServices setup)
} }
} }
@Test @Test
fun `unconsumed fungible states for owners`() { fun `unconsumed fungible states for owners`() {
database.transaction { database.transaction {
@ -1464,7 +1476,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
val results = vaultQuerySvc.queryBy<ContractState>(criteria) val results = vaultQuerySvc.queryBy<ContractState>(criteria)
// DOCEND VaultQueryExample5.2 // DOCEND VaultQueryExample5.2
assertThat(results.states).hasSize(1) // can only be 1 owner of a node (MEGA_CORP in this MockServices setup) assertThat(results.states).hasSize(2) // can only be 1 owner of a node (MEGA_CORP in this MockServices setup)
} }
} }
@ -1555,12 +1567,13 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test @Test
fun `unconsumed fungible assets for issuer party`() { fun `unconsumed fungible assets for issuer party`() {
database.transaction { database.transaction {
identitySvc.verifyAndRegisterIdentity(BOC_IDENTITY)
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (DUMMY_CASH_ISSUER)) services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (DUMMY_CASH_ISSUER))
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (BOC.ref(1))) services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (BOC.ref(1)))
// DOCSTART VaultQueryExample14 // DOCSTART VaultQueryExample14
val criteria = FungibleAssetQueryCriteria(issuerPartyName = listOf(BOC)) val criteria = FungibleAssetQueryCriteria(issuer = listOf(BOC))
val results = vaultQuerySvc.queryBy<FungibleAsset<*>>(criteria) val results = vaultQuerySvc.queryBy<FungibleAsset<*>>(criteria)
// DOCEND VaultQueryExample14 // DOCEND VaultQueryExample14
@ -1823,6 +1836,41 @@ class VaultQueryTests : TestDependencyInjectionBase() {
} }
} }
@Test
fun `unconsumed linear heads for single participant`() {
database.transaction {
identitySvc.verifyAndRegisterIdentity(ALICE_IDENTITY)
services.fillWithSomeTestLinearStates(1, "TEST1", listOf(ALICE))
services.fillWithSomeTestLinearStates(1)
services.fillWithSomeTestLinearStates(1, "TEST3")
val linearStateCriteria = LinearStateQueryCriteria(participants = listOf(ALICE))
val results = vaultQuerySvc.queryBy<LinearState>(linearStateCriteria)
assertThat(results.states).hasSize(1)
assertThat(results.states[0].state.data.linearId.externalId).isEqualTo("TEST1")
}
}
@Test
fun `unconsumed linear heads for multiple participants`() {
database.transaction {
identitySvc.verifyAndRegisterIdentity(ALICE_IDENTITY)
identitySvc.verifyAndRegisterIdentity(BOB_IDENTITY)
identitySvc.verifyAndRegisterIdentity(CHARLIE_IDENTITY)
services.fillWithSomeTestLinearStates(1, "TEST1", listOf(ALICE,BOB,CHARLIE))
services.fillWithSomeTestLinearStates(1)
services.fillWithSomeTestLinearStates(1, "TEST3")
val linearStateCriteria = LinearStateQueryCriteria(participants = listOf(ALICE,BOB,CHARLIE))
val results = vaultQuerySvc.queryBy<LinearState>(linearStateCriteria)
assertThat(results.states).hasSize(1)
assertThat(results.states[0].state.data.linearId.externalId).isEqualTo("TEST1")
}
}
@Test @Test
fun `unconsumed linear heads where external id is null`() { fun `unconsumed linear heads where external id is null`() {
database.transaction { database.transaction {

View File

@ -5,6 +5,7 @@ package net.corda.testing
import com.nhaarman.mockito_kotlin.spy import com.nhaarman.mockito_kotlin.spy
import com.nhaarman.mockito_kotlin.whenever import com.nhaarman.mockito_kotlin.whenever
import net.corda.contracts.asset.DUMMY_CASH_ISSUER
import net.corda.core.contracts.StateRef import net.corda.core.contracts.StateRef
import net.corda.core.crypto.* import net.corda.core.crypto.*
import net.corda.core.identity.Party import net.corda.core.identity.Party
@ -88,7 +89,9 @@ val BIG_CORP_PARTY_REF = BIG_CORP.ref(OpaqueBytes.of(1)).reference
val ALL_TEST_KEYS: List<KeyPair> get() = listOf(MEGA_CORP_KEY, MINI_CORP_KEY, ALICE_KEY, BOB_KEY, DUMMY_NOTARY_KEY) val ALL_TEST_KEYS: List<KeyPair> get() = listOf(MEGA_CORP_KEY, MINI_CORP_KEY, ALICE_KEY, BOB_KEY, DUMMY_NOTARY_KEY)
val MOCK_IDENTITIES = listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_NOTARY_IDENTITY) val DUMMY_CASH_ISSUER_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(DUMMY_CASH_ISSUER.party as Party)
val MOCK_IDENTITIES = listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)
val MOCK_IDENTITY_SERVICE: IdentityService get() = InMemoryIdentityService(MOCK_IDENTITIES, emptySet(), DUMMY_CA.certificate.cert) val MOCK_IDENTITY_SERVICE: IdentityService get() = InMemoryIdentityService(MOCK_IDENTITIES, emptySet(), DUMMY_CA.certificate.cert)
val MOCK_HOST_AND_PORT = NetworkHostAndPort("mockHost", 30000) val MOCK_HOST_AND_PORT = NetworkHostAndPort("mockHost", 30000)

View File

@ -61,6 +61,7 @@ val BOB: Party get() = Party(X500Name("CN=Bob Plc,O=Bob Plc,L=Rome,C=IT"), BOB_K
val CHARLIE_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(90)) } val CHARLIE_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(90)) }
/** Dummy individual identity for tests and simulations */ /** Dummy individual identity for tests and simulations */
val CHARLIE_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(CHARLIE)
val CHARLIE: Party get() = Party(X500Name("CN=Charlie Ltd,O=Charlie Ltd,L=Athens,C=GR"), CHARLIE_KEY.public) val CHARLIE: Party get() = Party(X500Name("CN=Charlie Ltd,O=Charlie Ltd,L=Athens,C=GR"), CHARLIE_KEY.public)
val DUMMY_REGULATOR_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(100)) } val DUMMY_REGULATOR_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(100)) }

View File

@ -42,6 +42,7 @@ class DummyDealContract : Contract {
override fun generateMappedObject(schema: MappedSchema): PersistentState { override fun generateMappedObject(schema: MappedSchema): PersistentState {
return when (schema) { return when (schema) {
is DummyDealStateSchemaV1 -> DummyDealStateSchemaV1.PersistentDummyDealState( is DummyDealStateSchemaV1 -> DummyDealStateSchemaV1.PersistentDummyDealState(
_participants = participants.toSet(),
uid = linearId uid = linearId
) )
else -> throw IllegalArgumentException("Unrecognised schema $schema") else -> throw IllegalArgumentException("Unrecognised schema $schema")

View File

@ -50,6 +50,7 @@ class DummyLinearContract : Contract {
override fun generateMappedObject(schema: MappedSchema): PersistentState { override fun generateMappedObject(schema: MappedSchema): PersistentState {
return when (schema) { return when (schema) {
is DummyLinearStateSchemaV1 -> DummyLinearStateSchemaV1.PersistentDummyLinearState( is DummyLinearStateSchemaV1 -> DummyLinearStateSchemaV1.PersistentDummyLinearState(
participants = participants.toMutableSet(),
externalId = linearId.externalId, externalId = linearId.externalId,
uuid = linearId.id, uuid = linearId.id,
linearString = linearString, linearString = linearString,
@ -58,6 +59,7 @@ class DummyLinearContract : Contract {
linearBoolean = linearBoolean linearBoolean = linearBoolean
) )
is DummyLinearStateSchemaV2 -> DummyLinearStateSchemaV2.PersistentDummyLinearState( is DummyLinearStateSchemaV2 -> DummyLinearStateSchemaV2.PersistentDummyLinearState(
_participants = participants.toSet(),
uid = linearId, uid = linearId,
linearString = linearString, linearString = linearString,
linearNumber = linearNumber, linearNumber = linearNumber,

View File

@ -119,14 +119,14 @@ fun ServiceHub.fillWithSomeTestCash(howMuch: Amount<Currency>,
issuedBy: PartyAndReference = DUMMY_CASH_ISSUER): Vault<Cash.State> { issuedBy: PartyAndReference = DUMMY_CASH_ISSUER): Vault<Cash.State> {
val amounts = calculateRandomlySizedAmounts(howMuch, atLeastThisManyStates, atMostThisManyStates, rng) val amounts = calculateRandomlySizedAmounts(howMuch, atLeastThisManyStates, atMostThisManyStates, rng)
val myKey: PublicKey = ownedBy?.owningKey ?: myInfo.legalIdentity.owningKey val myKey = ownedBy?.owningKey ?: myInfo.legalIdentity.owningKey
val me = AnonymousParty(myKey) val anonParty = AnonymousParty(myKey)
// We will allocate one state to one transaction, for simplicities sake. // We will allocate one state to one transaction, for simplicities sake.
val cash = Cash() val cash = Cash()
val transactions: List<SignedTransaction> = amounts.map { pennies -> val transactions: List<SignedTransaction> = amounts.map { pennies ->
val issuance = TransactionBuilder(null as Party?) val issuance = TransactionBuilder(null as Party?)
cash.generateIssue(issuance, Amount(pennies, Issued(issuedBy.copy(reference = ref), howMuch.token)), me, outputNotary) cash.generateIssue(issuance, Amount(pennies, Issued(issuedBy.copy(reference = ref), howMuch.token)), anonParty, outputNotary)
return@map issuerServices.signInitialTransaction(issuance, issuedBy.party.owningKey) return@map issuerServices.signInitialTransaction(issuance, issuedBy.party.owningKey)
} }

View File

@ -217,13 +217,15 @@ fun makeTestDatabaseProperties(): Properties {
fun makeTestIdentityService() = InMemoryIdentityService(MOCK_IDENTITIES, trustRoot = DUMMY_CA.certificate) fun makeTestIdentityService() = InMemoryIdentityService(MOCK_IDENTITIES, trustRoot = DUMMY_CA.certificate)
fun makeTestDatabaseAndMockServices(customSchemas: Set<MappedSchema> = setOf(CommercialPaperSchemaV1, DummyLinearStateSchemaV1, CashSchemaV1), keys: List<KeyPair> = listOf(MEGA_CORP_KEY)): Pair<CordaPersistence, MockServices> { fun makeTestDatabaseAndMockServices(customSchemas: Set<MappedSchema> = setOf(CommercialPaperSchemaV1, DummyLinearStateSchemaV1, CashSchemaV1),
keys: List<KeyPair> = listOf(MEGA_CORP_KEY),
identitySvc: ()-> IdentityService = { makeTestIdentityService() }): Pair<CordaPersistence, MockServices> {
val dataSourceProps = makeTestDataSourceProperties() val dataSourceProps = makeTestDataSourceProperties()
val databaseProperties = makeTestDatabaseProperties() val databaseProperties = makeTestDatabaseProperties()
val database = configureDatabase(dataSourceProps, databaseProperties, identitySvc = ::makeTestIdentityService) val database = configureDatabase(dataSourceProps, databaseProperties, identitySvc = identitySvc)
val mockService = database.transaction { val mockService = database.transaction {
val hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas), databaseProperties, identitySvc = ::makeTestIdentityService) val hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas), databaseProperties, identitySvc = identitySvc)
object : MockServices(*(keys.toTypedArray())) { object : MockServices(*(keys.toTypedArray())) {
override val vaultService: VaultService = makeVaultService(dataSourceProps, hibernateConfig) override val vaultService: VaultService = makeVaultService(dataSourceProps, hibernateConfig)

View File

@ -1,6 +1,7 @@
package net.corda.testing.schemas package net.corda.testing.schemas
import net.corda.core.contracts.UniqueIdentifier import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.identity.AbstractParty
import net.corda.core.schemas.CommonSchemaV1 import net.corda.core.schemas.CommonSchemaV1
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import javax.persistence.Entity import javax.persistence.Entity
@ -21,8 +22,11 @@ object DummyDealStateSchemaV1 : MappedSchema(schemaFamily = DummyDealStateSchema
@Table(name = "dummy_deal_states") @Table(name = "dummy_deal_states")
class PersistentDummyDealState( class PersistentDummyDealState(
/** parent attributes */ /** parent attributes */
@Transient
val _participants: Set<AbstractParty>,
@Transient @Transient
val uid: UniqueIdentifier val uid: UniqueIdentifier
) : CommonSchemaV1.LinearState(uid = uid) ) : CommonSchemaV1.LinearState(uid, _participants)
} }

View File

@ -1,13 +1,12 @@
package net.corda.testing.schemas package net.corda.testing.schemas
import net.corda.core.contracts.ContractState
import net.corda.core.identity.AbstractParty
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState import net.corda.core.schemas.PersistentState
import java.time.Instant import java.time.Instant
import java.util.* import java.util.*
import javax.persistence.Column import javax.persistence.*
import javax.persistence.Entity
import javax.persistence.Index
import javax.persistence.Table
/** /**
* An object used to fully qualify the [DummyLinearStateSchema] family name (i.e. independent of version). * An object used to fully qualify the [DummyLinearStateSchema] family name (i.e. independent of version).
@ -24,6 +23,12 @@ object DummyLinearStateSchemaV1 : MappedSchema(schemaFamily = DummyLinearStateSc
indexes = arrayOf(Index(name = "external_id_idx", columnList = "external_id"), indexes = arrayOf(Index(name = "external_id_idx", columnList = "external_id"),
Index(name = "uuid_idx", columnList = "uuid"))) Index(name = "uuid_idx", columnList = "uuid")))
class PersistentDummyLinearState( class PersistentDummyLinearState(
/** [ContractState] attributes */
/** X500Name of participant parties **/
@ElementCollection
var participants: MutableSet<AbstractParty>,
/** /**
* UniqueIdentifier * UniqueIdentifier
*/ */

View File

@ -1,6 +1,7 @@
package net.corda.testing.schemas package net.corda.testing.schemas
import net.corda.core.contracts.UniqueIdentifier import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.identity.AbstractParty
import net.corda.core.schemas.CommonSchemaV1 import net.corda.core.schemas.CommonSchemaV1
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import javax.persistence.Column import javax.persistence.Column
@ -25,7 +26,10 @@ object DummyLinearStateSchemaV2 : MappedSchema(schemaFamily = DummyLinearStateSc
@Column(name = "linear_boolean") var linearBoolean: Boolean, @Column(name = "linear_boolean") var linearBoolean: Boolean,
/** parent attributes */ /** parent attributes */
@Transient
val _participants: Set<AbstractParty>,
@Transient @Transient
val uid: UniqueIdentifier val uid: UniqueIdentifier
) : CommonSchemaV1.LinearState(uid = uid) ) : CommonSchemaV1.LinearState(uid, _participants)
} }