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.crypto.SecureHash
import net.corda.core.flows.FlowException
import net.corda.core.identity.AbstractParty
import net.corda.core.node.services.vault.QueryCriteria
import net.corda.core.serialization.CordaSerializable
import net.corda.core.toFuture
@ -135,8 +136,7 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
val recordedTime: Instant,
val consumedTime: Instant?,
val status: Vault.StateStatus,
val notaryName: String,
val notaryKey: String,
val notary: AbstractParty?,
val lockId: String?,
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,
val contractStateTypes: Set<Class<out ContractState>>? = null,
val stateRefs: List<StateRef>? = null,
val notaryName: List<X500Name>? = null,
val notary: List<AbstractParty>? = null,
val softLockingCondition: SoftLockingCondition? = null,
val timeCondition: TimeCondition? = null) : CommonQueryCriteria() {
override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> {
@ -81,7 +81,7 @@ sealed class QueryCriteria {
data class FungibleAssetQueryCriteria @JvmOverloads constructor(val participants: List<AbstractParty>? = null,
val owner: List<AbstractParty>? = null,
val quantity: ColumnPredicate<Long>? = null,
val issuerPartyName: List<AbstractParty>? = null,
val issuer: List<AbstractParty>? = null,
val issuerRef: List<OpaqueBytes>? = null,
override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED) : CommonQueryCriteria() {
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 {
/** Vault States */
NOTARY_NAME("notaryName"),
NOTARY_NAME("notary"),
CONTRACT_TYPE("contractStateClassName"),
STATE_STATUS("stateStatus"),
RECORDED_TIME("recordedTime"),

View File

@ -17,10 +17,17 @@ object CommonSchema
/**
* 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
open class LinearState(
/** [ContractState] attributes */
/** X500Name of participant parties **/
@ElementCollection
@Column(name = "participants")
var participants: MutableSet<AbstractParty>? = null,
/**
* Represents a [LinearState] [UniqueIdentifier]
*/
@ -31,18 +38,26 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers
var uuid: UUID
) : 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
open class FungibleState(
/** [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 */
@OneToOne(cascade = arrayOf(CascadeType.ALL))
var ownerKey: CommonSchemaV1.Party,
/** X500Name of owner party **/
@Column(name = "owner_name")
var owner: AbstractParty,
/** [FungibleAsset] attributes
*
@ -55,42 +70,12 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers
var quantity: Long,
/** 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")
var issuerRef: ByteArray
) : 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())
}
) : PersistentState()
}

View File

@ -2,6 +2,7 @@ package net.corda.core.schemas.converters
import net.corda.core.identity.AbstractParty
import net.corda.core.node.services.IdentityService
import net.corda.core.utilities.loggerFor
import org.bouncycastle.asn1.x500.X500Name
import javax.persistence.AttributeConverter
import javax.persistence.Converter
@ -17,9 +18,15 @@ class AbstractPartyToX500NameAsStringConverter(identitySvc: () -> IdentityServic
identitySvc()
}
companion object {
val log = loggerFor<AbstractPartyToX500NameAsStringConverter>()
}
override fun convertToDatabaseColumn(party: AbstractParty?): String? {
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
}
@ -27,7 +34,8 @@ class AbstractPartyToX500NameAsStringConverter(identitySvc: () -> IdentityServic
override fun convertToEntityAttribute(dbData: String?): AbstractParty? {
dbData?.let {
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
}

View File

@ -44,11 +44,14 @@ class ContractUpgradeFlowTest {
@Before
fun setup() {
mockNet = MockNetwork()
val nodes = mockNet.createSomeNodes()
val nodes = mockNet.createSomeNodes(notaryKeyPair = null) // prevent generation of notary override
a = nodes.partyNodes[0]
b = nodes.partyNodes[1]
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

View File

@ -12,6 +12,7 @@ import net.corda.core.flows.FlowLogic
import net.corda.core.flows.InitiatedBy
import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.*
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party
import net.corda.core.node.ServiceHub
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 fungibleCriteria = QueryCriteria.FungibleAssetQueryCriteria(owner = ourParties)
val notaryName = if (notary != null) notary.name else serviceHub.networkMapCache.getAnyNotary()!!.name
val vaultCriteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(notaryName = listOf(notaryName))
val notaries = notary ?: serviceHub.networkMapCache.getAnyNotary()
val vaultCriteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(notary = listOf(notaries as AbstractParty))
val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.equal(amountRequired.token.product.currencyCode) }
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.identity.AbstractParty
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.Emoji
import net.corda.core.node.ServiceHub
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 {
return when (schema) {
is CashSchemaV1 -> CashSchemaV1.PersistentCashState(
owner = this.owner.owningKey.toBase58String(),
owner = this.owner,
pennies = this.amount.quantity,
currency = this.amount.token.product.currencyCode,
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)
""" +
(if (notary != null)
" AND vs.notary_key = '${notary.owningKey.toBase58String()}'" else "") +
" AND vs.notary_name = '${notary.name}'" else "") +
(if (onlyFromIssuerParties.isNotEmpty())
" AND ccs.issuer_key IN ($issuerKeysStr)" else "") +
(if (withIssuerRefs.isNotEmpty())

View File

@ -1,5 +1,6 @@
package net.corda.schemas
import net.corda.core.identity.AbstractParty
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
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"),
Index(name = "pennies_idx", columnList = "pennies")))
class PersistentCashState(
@Column(name = "owner_key")
var owner: String,
/** X500Name of owner party **/
@Column(name = "owner_name")
var owner: AbstractParty,
@Column(name = "pennies")
var pennies: Long,

View File

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

View File

@ -13,7 +13,7 @@ import javax.persistence.Table
* [VaultFungibleState] abstract schema
*/
object SampleCashSchemaV2 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 2,
mappedTypes = listOf(PersistentCashState::class.java, CommonSchemaV1.Party::class.java)) {
mappedTypes = listOf(PersistentCashState::class.java)) {
@Entity
@Table(name = "cash_states_v2",
indexes = arrayOf(Index(name = "ccy_code_idx2", columnList = "ccy_code")))
@ -33,5 +33,5 @@ object SampleCashSchemaV2 : MappedSchema(schemaFamily = CashSchema.javaClass, ve
val _issuerParty: AbstractParty,
@Transient
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.
*/
object SampleCashSchemaV3 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 3,
mappedTypes = listOf(PersistentCashState::class.java, CommonSchemaV1.Party::class.java)) {
mappedTypes = listOf(PersistentCashState::class.java)) {
@Entity
@Table(name = "cash_states_v3")
class PersistentCashState(
/** [ContractState] attributes */
@OneToMany(cascade = arrayOf(CascadeType.ALL))
var participants: Set<CommonSchemaV1.Party>,
@OneToOne(cascade = arrayOf(CascadeType.ALL))
var owner: CommonSchemaV1.Party,
/** X500Name of participant parties **/
@ElementCollection
var participants: MutableSet<AbstractParty>? = null,
/** X500Name of owner party **/
@Column(name = "owner_name")
var owner: AbstractParty,
@Column(name = "pennies")
var pennies: Long,
@ -28,18 +31,11 @@ object SampleCashSchemaV3 : MappedSchema(schemaFamily = CashSchema.javaClass, ve
@Column(name = "ccy_code", length = 3)
var currency: String,
@OneToOne(cascade = arrayOf(CascadeType.ALL))
var issuerParty: CommonSchemaV1.Party,
/** X500Name of issuer party **/
@Column(name = "issuer_name")
var issuer: AbstractParty,
@Column(name = "issuer_ref")
var issuerRef: ByteArray
) : 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)
}
) : PersistentState()
}

View File

@ -14,7 +14,7 @@ import javax.persistence.Table
* [VaultFungibleState] abstract schema
*/
object SampleCommercialPaperSchemaV2 : MappedSchema(schemaFamily = CommercialPaperSchema.javaClass, version = 1,
mappedTypes = listOf(PersistentCommercialPaperState::class.java, CommonSchemaV1.Party::class.java)) {
mappedTypes = listOf(PersistentCommercialPaperState::class.java)) {
@Entity
@Table(name = "cp_states_v2",
indexes = arrayOf(Index(name = "ccy_code_index2", columnList = "ccy_code"),
@ -44,5 +44,5 @@ object SampleCommercialPaperSchemaV2 : MappedSchema(schemaFamily = CommercialPap
val _issuerParty: AbstractParty,
@Transient
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")
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] */
@get:Column(name = "contract_state_class_name")
var contractStateClassName: String

View File

@ -314,7 +314,6 @@ class VaultSchemaTest : TestDependencyInjectionBase() {
contractStateClassName = state.data.javaClass.name
contractState = state.serialize().bytes
notaryName = state.notary.name.toString()
notaryKey = state.notary.owningKey.toBase58String()
recordedTime = Instant.now()
}
}
@ -655,15 +654,12 @@ class VaultSchemaTest : TestDependencyInjectionBase() {
@Test
fun insertWithBigCompositeKey() {
val keys = (1..314).map { generateKeyPair().public }
val bigNotaryKey = CompositeKey.Builder().addKeys(keys).build()
val vaultStEntity = VaultStatesEntity().apply {
txId = SecureHash.randomSHA256().toString()
index = 314
stateStatus = Vault.StateStatus.UNCONSUMED
contractStateClassName = VaultNoopContract.VaultNoopState::class.java.name
notaryName = "Huge distributed notary"
notaryKey = bigNotaryKey.toBase58String()
recordedTime = Instant.now()
}
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.vault.*
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.PersistentStateRef
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.toHexString
import net.corda.core.utilities.trace
import org.bouncycastle.asn1.x500.X500Name
import java.util.*
import javax.persistence.Tuple
import javax.persistence.criteria.*
@ -68,9 +66,8 @@ class HibernateQueryCriteriaParser(val contractType: Class<out ContractState>,
}
// notary names
criteria.notaryName?.let {
val notaryNames = (criteria.notaryName as List<X500Name>).map { it.toString() }
predicateSet.add(criteriaBuilder.and(vaultStates.get<String>("notaryName").`in`(notaryNames)))
criteria.notary?.let {
predicateSet.add(criteriaBuilder.and(vaultStates.get<AbstractParty>("notary").`in`(criteria.notary)))
}
// state references
@ -243,10 +240,8 @@ class HibernateQueryCriteriaParser(val contractType: Class<out ContractState>,
// owner
criteria.owner?.let {
val ownerKeys = criteria.owner as List<AbstractParty>
val joinFungibleStateToParty = vaultFungibleStates.join<VaultSchemaV1.VaultFungibleStates, CommonSchemaV1.Party>("issuerParty")
val owners = ownerKeys.map { it.nameOrNull()?.toString() ?: it.toString()}
predicateSet.add(criteriaBuilder.and(joinFungibleStateToParty.get<CommonSchemaV1.Party>("name").`in`(owners)))
val owners = criteria.owner as List<AbstractParty>
predicateSet.add(criteriaBuilder.and(vaultFungibleStates.get<AbstractParty>("owner").`in`(owners)))
}
// quantity
@ -255,11 +250,9 @@ class HibernateQueryCriteriaParser(val contractType: Class<out ContractState>,
}
// issuer party
criteria.issuerPartyName?.let {
val issuerParties = criteria.issuerPartyName as List<AbstractParty>
val joinFungibleStateToParty = vaultFungibleStates.join<VaultSchemaV1.VaultFungibleStates, CommonSchemaV1.Party>("issuerParty")
val issuerPartyNames = issuerParties.map { it.nameOrNull().toString() }
predicateSet.add(criteriaBuilder.and(joinFungibleStateToParty.get<CommonSchemaV1.Party>("name").`in`(issuerPartyNames)))
criteria.issuer?.let {
val issuerParties = criteria.issuer as List<AbstractParty>
predicateSet.add(criteriaBuilder.and(vaultFungibleStates.get<AbstractParty>("issuer").`in`(issuerParties)))
}
// issuer reference
@ -271,9 +264,8 @@ class HibernateQueryCriteriaParser(val contractType: Class<out ContractState>,
// participants
criteria.participants?.let {
val participants = criteria.participants as List<AbstractParty>
val joinFungibleStateToParty = vaultFungibleStates.join<VaultSchemaV1.VaultFungibleStates, CommonSchemaV1.Party>("participants")
val participantKeys = participants.map { it.nameOrNull().toString() }
predicateSet.add(criteriaBuilder.and(joinFungibleStateToParty.get<CommonSchemaV1.Party>("name").`in`(participantKeys)))
val joinLinearStateToParty = vaultFungibleStates.joinSet<VaultSchemaV1.VaultLinearStates, AbstractParty>("participants")
predicateSet.add(criteriaBuilder.and(joinLinearStateToParty.`in`(participants)))
criteriaQuery.distinct(true)
}
return predicateSet
@ -310,9 +302,8 @@ class HibernateQueryCriteriaParser(val contractType: Class<out ContractState>,
// deal participants
criteria.participants?.let {
val participants = criteria.participants as List<AbstractParty>
val joinLinearStateToParty = vaultLinearStates.join<VaultSchemaV1.VaultLinearStates, CommonSchemaV1.Party>("participants")
val participantKeys = participants.map { it.nameOrNull().toString() }
predicateSet.add(criteriaBuilder.and(joinLinearStateToParty.get<CommonSchemaV1.Party>("name").`in`(participantKeys)))
val joinLinearStateToParty = vaultLinearStates.joinSet<VaultSchemaV1.VaultLinearStates, AbstractParty>("participants")
predicateSet.add(criteriaBuilder.and(joinLinearStateToParty.`in`(participants)))
criteriaQuery.distinct(true)
}
return predicateSet

View File

@ -119,7 +119,14 @@ class HibernateVaultQueryImpl(hibernateConfig: HibernateConfiguration,
val vaultState = result[0] as VaultSchemaV1.VaultStates
val stateRef = StateRef(SecureHash.parse(vaultState.stateRef!!.txId!!), vaultState.stateRef!!.index!!)
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))
}
else {

View File

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

View File

@ -1,9 +1,9 @@
package net.corda.node.services.vault
import net.corda.core.contracts.ContractState
import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.identity.AbstractParty
import net.corda.core.node.services.Vault
import net.corda.core.schemas.CommonSchemaV1
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import net.corda.core.serialization.CordaSerializable
@ -22,17 +22,14 @@ object VaultSchema
*/
@CordaSerializable
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
@Table(name = "vault_states",
indexes = arrayOf(Index(name = "state_status_idx", columnList = "state_status")))
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")
var notaryName: String,
@Column(name = "notary_key", length = 65535) // TODO What is the upper limit on size of CompositeKey?
var notaryKey: String,
var notary: AbstractParty,
/** references a concrete ContractState that is [QueryableState] and has a [MappedSchema] */
@Column(name = "contract_state_class_name")
@ -71,8 +68,13 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
Index(name = "uuid_index", columnList = "uuid")))
class VaultLinearStates(
/** [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]
@ -86,18 +88,23 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
constructor(uid: UniqueIdentifier, _participants: List<AbstractParty>) :
this(externalId = uid.externalId,
uuid = uid.id,
participants = _participants.map{ CommonSchemaV1.Party(it) }.toSet() )
participants = _participants.toMutableSet())
}
@Entity
@Table(name = "vault_fungible_states")
class VaultFungibleStates(
/** [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 */
@Column(name = "owner_id")
/** X500Name of owner party **/
@Column(name = "owner_name")
var owner: AbstractParty,
/** [FungibleAsset] attributes
@ -111,8 +118,10 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
var quantity: Long,
/** 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")
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>) :
this(owner = _owner,
quantity = _quantity,
issuerParty = CommonSchemaV1.Party(_issuerParty),
issuer = _issuerParty,
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.identity.AbstractParty;
import net.corda.core.messaging.DataFeed;
import net.corda.core.node.services.Vault;
import net.corda.core.node.services.VaultQueryException;
import net.corda.core.node.services.VaultQueryService;
import net.corda.core.node.services.*;
import net.corda.core.node.services.vault.*;
import net.corda.core.node.services.vault.QueryCriteria.LinearStateQueryCriteria;
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.TestConstants.*;
import static net.corda.testing.node.MockServicesKt.makeTestDatabaseAndMockServices;
import static net.corda.testing.node.MockServicesKt.makeTestIdentityService;
import static org.assertj.core.api.Assertions.assertThat;
public class VaultQueryJavaTests extends TestDependencyInjectionBase {
@ -58,7 +57,9 @@ public class VaultQueryJavaTests extends TestDependencyInjectionBase {
ArrayList<KeyPair> keys = new ArrayList<>();
keys.add(getMEGA_CORP_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());
database = databaseAndServices.getFirst();
services = databaseAndServices.getSecond();

View File

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

View File

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

View File

@ -69,11 +69,11 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() {
lockId: UUID = UUID.randomUUID(),
withIssuerRefs: Set<OpaqueBytes>? = null): List<StateAndRef<Cash.State>> {
val notaryName = if (notary != null) listOf(notary.name) else null
var baseCriteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(notaryName = notaryName)
val notaries = if (notary != null) listOf(notary) else null
var baseCriteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(notary = notaries)
if (onlyFromIssuerParties != null || withIssuerRefs != null) {
baseCriteria = baseCriteria.and(QueryCriteria.FungibleAssetQueryCriteria(
issuerPartyName = onlyFromIssuerParties?.toList(),
issuer = onlyFromIssuerParties?.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.toBase58String
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.services.*
import net.corda.core.node.services.vault.*
import net.corda.core.node.services.vault.QueryCriteria.*
@ -50,11 +51,20 @@ class VaultQueryTests : TestDependencyInjectionBase() {
lateinit var notaryServices: MockServices
val vaultSvc: VaultService get() = services.vaultService
val vaultQuerySvc: VaultQueryService get() = services.vaultQueryService
val identitySvc: IdentityService = makeTestIdentityService()
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
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
services = databaseAndServices.second
notaryServices = MockServices(DUMMY_NOTARY_KEY, DUMMY_CASH_ISSUER_KEY, BOC_KEY, MEGA_CORP_KEY)
@ -71,7 +81,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Ignore
@Test
fun createPersistentTestDb() {
val database = configureDatabase(makePersistentDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = ::makeTestIdentityService)
val database = configureDatabase(makePersistentDataSourceProperties(), makeTestDatabaseProperties(), identitySvc = { identitySvc })
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
fun `unconsumed states by notary`() {
database.transaction {
@ -408,7 +415,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
// DOCSTART VaultQueryExample4
val criteria = VaultQueryCriteria(notaryName = listOf(CASH_NOTARY.name))
val criteria = VaultQueryCriteria(notary = listOf(CASH_NOTARY))
val results = vaultQuerySvc.queryBy<ContractState>(criteria)
// DOCEND VaultQueryExample4
assertThat(results.states).hasSize(3)
@ -418,6 +425,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun `unconsumed linear states for single participant`() {
database.transaction {
identitySvc.verifyAndRegisterIdentity(BIG_CORP_IDENTITY)
services.fillWithSomeTestLinearStates(2, "TEST", participants = listOf(MEGA_CORP, MINI_CORP))
services.fillWithSomeTestDeals(listOf("456"), participants = listOf(MEGA_CORP, BIG_CORP))
@ -433,13 +441,14 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun `unconsumed linear states for two participants`() {
database.transaction {
identitySvc.verifyAndRegisterIdentity(BIG_CORP_IDENTITY)
services.fillWithSomeTestLinearStates(2, "TEST", participants = listOf(MEGA_CORP, MINI_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
val criteria = LinearStateQueryCriteria(participants = listOf(MEGA_CORP, MINI_CORP))
val criteria = LinearStateQueryCriteria(participants = listOf(BIG_CORP, MINI_CORP))
val results = vaultQuerySvc.queryBy<ContractState>(criteria)
// DOCEND VaultQueryExample5
@ -793,6 +802,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun `aggregate functions sum by issuer and currency and sort by aggregate sum`() {
database.transaction {
identitySvc.verifyAndRegisterIdentity(BOC_IDENTITY)
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))
@ -1026,6 +1036,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
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 criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
vaultQuerySvc.queryBy<ContractState>(criteria, paging = pagingSpec)
@ -1375,7 +1386,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
database.transaction {
val parties = listOf(MEGA_CORP)
val parties = listOf(MINI_CORP)
services.fillWithSomeTestLinearStates(2, "TEST")
services.fillWithSomeTestDeals(listOf("456"), parties)
@ -1395,13 +1406,14 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun `unconsumed fungible assets for specific issuer party and refs`() {
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 = (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(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))
val results = vaultQuerySvc.queryBy<FungibleAsset<*>>(criteria)
assertThat(results.states).hasSize(2)
@ -1424,11 +1436,12 @@ class VaultQueryTests : TestDependencyInjectionBase() {
val chfCashIssuerServices = MockServices(chfCashIssuerKey)
database.transaction {
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.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)
assertThat(results.states).hasSize(2)
}
@ -1438,17 +1451,16 @@ class VaultQueryTests : TestDependencyInjectionBase() {
fun `unconsumed fungible assets by owner`() {
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),
issuedBy = MEGA_CORP.ref(0), ownedBy = (MEGA_CORP))
issuedBy = MEGA_CORP.ref(0), ownedBy = (MINI_CORP))
val criteria = FungibleAssetQueryCriteria(owner = listOf(MEGA_CORP))
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
fun `unconsumed fungible states for owners`() {
database.transaction {
@ -1464,7 +1476,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
val results = vaultQuerySvc.queryBy<ContractState>(criteria)
// 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
fun `unconsumed fungible assets for issuer party`() {
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 = (BOC.ref(1)))
// DOCSTART VaultQueryExample14
val criteria = FungibleAssetQueryCriteria(issuerPartyName = listOf(BOC))
val criteria = FungibleAssetQueryCriteria(issuer = listOf(BOC))
val results = vaultQuerySvc.queryBy<FungibleAsset<*>>(criteria)
// 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
fun `unconsumed linear heads where external id is null`() {
database.transaction {

View File

@ -5,6 +5,7 @@ package net.corda.testing
import com.nhaarman.mockito_kotlin.spy
import com.nhaarman.mockito_kotlin.whenever
import net.corda.contracts.asset.DUMMY_CASH_ISSUER
import net.corda.core.contracts.StateRef
import net.corda.core.crypto.*
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 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_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)) }
/** 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 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 {
return when (schema) {
is DummyDealStateSchemaV1 -> DummyDealStateSchemaV1.PersistentDummyDealState(
_participants = participants.toSet(),
uid = linearId
)
else -> throw IllegalArgumentException("Unrecognised schema $schema")

View File

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

View File

@ -119,14 +119,14 @@ fun ServiceHub.fillWithSomeTestCash(howMuch: Amount<Currency>,
issuedBy: PartyAndReference = DUMMY_CASH_ISSUER): Vault<Cash.State> {
val amounts = calculateRandomlySizedAmounts(howMuch, atLeastThisManyStates, atMostThisManyStates, rng)
val myKey: PublicKey = ownedBy?.owningKey ?: myInfo.legalIdentity.owningKey
val me = AnonymousParty(myKey)
val myKey = ownedBy?.owningKey ?: myInfo.legalIdentity.owningKey
val anonParty = AnonymousParty(myKey)
// We will allocate one state to one transaction, for simplicities sake.
val cash = Cash()
val transactions: List<SignedTransaction> = amounts.map { pennies ->
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)
}

View File

@ -217,13 +217,15 @@ fun makeTestDatabaseProperties(): Properties {
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 databaseProperties = makeTestDatabaseProperties()
val database = configureDatabase(dataSourceProps, databaseProperties, identitySvc = ::makeTestIdentityService)
val database = configureDatabase(dataSourceProps, databaseProperties, identitySvc = identitySvc)
val mockService = database.transaction {
val hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas), databaseProperties, identitySvc = ::makeTestIdentityService)
val hibernateConfig = HibernateConfiguration(NodeSchemaService(customSchemas), databaseProperties, identitySvc = identitySvc)
object : MockServices(*(keys.toTypedArray())) {
override val vaultService: VaultService = makeVaultService(dataSourceProps, hibernateConfig)

View File

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

View File

@ -1,13 +1,12 @@
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.PersistentState
import java.time.Instant
import java.util.*
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.Index
import javax.persistence.Table
import javax.persistence.*
/**
* 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"),
Index(name = "uuid_idx", columnList = "uuid")))
class PersistentDummyLinearState(
/** [ContractState] attributes */
/** X500Name of participant parties **/
@ElementCollection
var participants: MutableSet<AbstractParty>,
/**
* UniqueIdentifier
*/

View File

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