mirror of
https://github.com/corda/corda.git
synced 2025-02-20 09:26:41 +00:00
CORDA-1999 Changed isRelevant to relevancyStatus. (#3966)
* Changed isRelevant to relevancyStatus. * Fix cash selection from breaking. * Fixed non-backwards compatible API change. * Updated schema migration changelog. * Updated comment.
This commit is contained in:
parent
492c25fedd
commit
c4d86b1b26
@ -160,7 +160,7 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
|
||||
val notary: AbstractParty?,
|
||||
val lockId: String?,
|
||||
val lockUpdateTime: Instant?,
|
||||
val isRelevant: Vault.RelevancyStatus?
|
||||
val relevancyStatus: Vault.RelevancyStatus?
|
||||
) {
|
||||
constructor(ref: StateRef,
|
||||
contractStateClassName: String,
|
||||
|
@ -73,7 +73,7 @@ sealed class QueryCriteria : GenericQueryCriteria<QueryCriteria, IQueryCriteriaP
|
||||
|
||||
abstract class CommonQueryCriteria : QueryCriteria() {
|
||||
abstract val status: Vault.StateStatus
|
||||
open val isRelevant: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL
|
||||
open val relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL
|
||||
abstract val contractStateTypes: Set<Class<out ContractState>>?
|
||||
override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> {
|
||||
return parser.parseCriteria(this)
|
||||
@ -90,7 +90,7 @@ sealed class QueryCriteria : GenericQueryCriteria<QueryCriteria, IQueryCriteriaP
|
||||
val notary: List<AbstractParty>? = null,
|
||||
val softLockingCondition: SoftLockingCondition? = null,
|
||||
val timeCondition: TimeCondition? = null,
|
||||
override val isRelevant: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL
|
||||
override val relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL
|
||||
) : CommonQueryCriteria() {
|
||||
override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> {
|
||||
super.visit(parser)
|
||||
@ -125,15 +125,15 @@ sealed class QueryCriteria : GenericQueryCriteria<QueryCriteria, IQueryCriteriaP
|
||||
val externalId: List<String>? = null,
|
||||
override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED,
|
||||
override val contractStateTypes: Set<Class<out ContractState>>? = null,
|
||||
override val isRelevant: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL
|
||||
override val relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL
|
||||
) : CommonQueryCriteria() {
|
||||
constructor(
|
||||
participants: List<AbstractParty>? = null,
|
||||
linearId: List<UniqueIdentifier>? = null,
|
||||
status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED,
|
||||
contractStateTypes: Set<Class<out ContractState>>? = null,
|
||||
isRelevant: Vault.RelevancyStatus
|
||||
) : this(participants, linearId?.map { it.id }, linearId?.mapNotNull { it.externalId }, status, contractStateTypes, isRelevant)
|
||||
relevancyStatus: Vault.RelevancyStatus
|
||||
) : this(participants, linearId?.map { it.id }, linearId?.mapNotNull { it.externalId }, status, contractStateTypes, relevancyStatus)
|
||||
|
||||
constructor(
|
||||
participants: List<AbstractParty>? = null,
|
||||
@ -175,7 +175,7 @@ sealed class QueryCriteria : GenericQueryCriteria<QueryCriteria, IQueryCriteriaP
|
||||
val issuerRef: List<OpaqueBytes>? = null,
|
||||
override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED,
|
||||
override val contractStateTypes: Set<Class<out ContractState>>? = null,
|
||||
override val isRelevant: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL
|
||||
override val relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL
|
||||
) : CommonQueryCriteria() {
|
||||
override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> {
|
||||
super.visit(parser)
|
||||
@ -215,7 +215,7 @@ sealed class QueryCriteria : GenericQueryCriteria<QueryCriteria, IQueryCriteriaP
|
||||
val expression: CriteriaExpression<L, Boolean>,
|
||||
override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED,
|
||||
override val contractStateTypes: Set<Class<out ContractState>>? = null,
|
||||
override val isRelevant: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL
|
||||
override val relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL
|
||||
) : CommonQueryCriteria() {
|
||||
override fun visit(parser: IQueryCriteriaParser): Collection<Predicate> {
|
||||
super.visit(parser)
|
||||
|
@ -105,7 +105,7 @@ internal class UseRefState(val linearId: UniqueIdentifier) : FlowLogic<SignedTra
|
||||
val notary = serviceHub.networkMapCache.notaryIdentities.first()
|
||||
val query = QueryCriteria.LinearStateQueryCriteria(
|
||||
linearId = listOf(linearId),
|
||||
isRelevant = Vault.RelevancyStatus.ALL
|
||||
relevancyStatus = Vault.RelevancyStatus.ALL
|
||||
)
|
||||
val referenceState = serviceHub.vaultService.queryBy<ContractState>(query).states.single()
|
||||
return subFlow(FinalityFlow(
|
||||
|
@ -22,7 +22,7 @@ private fun generateCashSumCriteria(currency: Currency): QueryCriteria {
|
||||
|
||||
val ccyIndex = builder { CashSchemaV1.PersistentCashState::currency.equal(currency.currencyCode) }
|
||||
// This query should only return cash states the calling node is a participant of (meaning they can be modified/spent).
|
||||
val ccyCriteria = QueryCriteria.VaultCustomQueryCriteria(ccyIndex, isRelevant = Vault.RelevancyStatus.RELEVANT)
|
||||
val ccyCriteria = QueryCriteria.VaultCustomQueryCriteria(ccyIndex, relevancyStatus = Vault.RelevancyStatus.RELEVANT)
|
||||
return sumCriteria.and(ccyCriteria)
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ private fun generateCashSumsCriteria(): QueryCriteria {
|
||||
orderBy = Sort.Direction.DESC)
|
||||
}
|
||||
// This query should only return cash states the calling node is a participant of (meaning they can be modified/spent).
|
||||
return QueryCriteria.VaultCustomQueryCriteria(sum, isRelevant = Vault.RelevancyStatus.RELEVANT)
|
||||
return QueryCriteria.VaultCustomQueryCriteria(sum, relevancyStatus = Vault.RelevancyStatus.RELEVANT)
|
||||
}
|
||||
|
||||
private fun rowsToAmount(currency: Currency, rows: Vault.Page<FungibleAsset<*>>): Amount<Currency> {
|
||||
|
@ -40,7 +40,7 @@ class CashSelectionH2Impl : AbstractCashSelection() {
|
||||
FROM vault_states AS vs, contract_cash_states AS ccs
|
||||
WHERE vs.transaction_id = ccs.transaction_id AND vs.output_index = ccs.output_index
|
||||
AND vs.state_status = 0
|
||||
AND vs.is_relevant = 0
|
||||
AND vs.relevancy_status = 0
|
||||
AND ccs.ccy_code = ? and @t < ?
|
||||
AND (vs.lock_id = ? OR vs.lock_id is null)
|
||||
""" +
|
||||
|
@ -42,7 +42,7 @@ class CashSelectionPostgreSQLImpl : AbstractCashSelection() {
|
||||
FROM vault_states AS vs, contract_cash_states AS ccs
|
||||
WHERE vs.transaction_id = ccs.transaction_id AND vs.output_index = ccs.output_index
|
||||
AND vs.state_status = 0
|
||||
AND vs.is_relevant = 0
|
||||
AND vs.relevancy_status = 0
|
||||
AND ccs.ccy_code = ?
|
||||
AND (vs.lock_id = ? OR vs.lock_id is null)
|
||||
""" +
|
||||
|
@ -58,7 +58,7 @@ class CashSelectionSQLServerImpl : AbstractCashSelection() {
|
||||
ON vs.transaction_id = ccs.transaction_id AND vs.output_index = ccs.output_index
|
||||
WHERE
|
||||
vs.state_status = 0
|
||||
AND vs.is_relevant = 0
|
||||
AND vs.relevancy_status = 0
|
||||
AND ccs.ccy_code = ?
|
||||
AND (vs.lock_id = ? OR vs.lock_id IS NULL)
|
||||
"""
|
||||
|
@ -533,16 +533,16 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
||||
}
|
||||
|
||||
// state relevance.
|
||||
if (criteria.isRelevant != Vault.RelevancyStatus.ALL) {
|
||||
val predicateID = Pair(VaultSchemaV1.VaultStates::isRelevant.name, EQUAL)
|
||||
if (criteria.relevancyStatus != Vault.RelevancyStatus.ALL) {
|
||||
val predicateID = Pair(VaultSchemaV1.VaultStates::relevancyStatus.name, EQUAL)
|
||||
if (commonPredicates.containsKey(predicateID)) {
|
||||
val existingStatus = ((commonPredicates[predicateID] as ComparisonPredicate).rightHandOperand as LiteralExpression).literal
|
||||
if (existingStatus != criteria.isRelevant) {
|
||||
log.warn("Overriding previous attribute [${VaultSchemaV1.VaultStates::isRelevant.name}] value $existingStatus with ${criteria.status}")
|
||||
commonPredicates.replace(predicateID, criteriaBuilder.equal(vaultStates.get<Vault.RelevancyStatus>(VaultSchemaV1.VaultStates::isRelevant.name), criteria.isRelevant))
|
||||
if (existingStatus != criteria.relevancyStatus) {
|
||||
log.warn("Overriding previous attribute [${VaultSchemaV1.VaultStates::relevancyStatus.name}] value $existingStatus with ${criteria.status}")
|
||||
commonPredicates.replace(predicateID, criteriaBuilder.equal(vaultStates.get<Vault.RelevancyStatus>(VaultSchemaV1.VaultStates::relevancyStatus.name), criteria.relevancyStatus))
|
||||
}
|
||||
} else {
|
||||
commonPredicates[predicateID] = criteriaBuilder.equal(vaultStates.get<Vault.RelevancyStatus>(VaultSchemaV1.VaultStates::isRelevant.name), criteria.isRelevant)
|
||||
commonPredicates[predicateID] = criteriaBuilder.equal(vaultStates.get<Vault.RelevancyStatus>(VaultSchemaV1.VaultStates::relevancyStatus.name), criteria.relevancyStatus)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,10 +114,12 @@ class NodeVaultService(
|
||||
// For EVERY state to be committed to the vault, this checks whether it is spendable by the recording
|
||||
// node. The behaviour is as follows:
|
||||
//
|
||||
// 1) All vault updates marked as RELEVANT will, of, course all have isRelevant = true.
|
||||
// 2) For ALL_VISIBLE updates, those which are not relevant according to the relevancy rules will have isRelevant = false.
|
||||
// 1) All vault updates marked as RELEVANT will, of course, all have relevancy_status = 1 in the
|
||||
// "vault_states" table.
|
||||
// 2) For ALL_VISIBLE updates, those which are not relevant according to the relevancy rules will have
|
||||
// relevancy_status = 0 in the "vault_states" table.
|
||||
//
|
||||
// This is useful when it comes to querying for fungible states, when we do not want non-relevant states
|
||||
// This is useful when it comes to querying for fungible states, when we do not want irrelevant states
|
||||
// included in the result.
|
||||
//
|
||||
// The same functionality could be obtained by passing in a list of participants to the vault query,
|
||||
@ -135,7 +137,7 @@ class NodeVaultService(
|
||||
contractStateClassName = stateAndRef.value.state.data.javaClass.name,
|
||||
stateStatus = Vault.StateStatus.UNCONSUMED,
|
||||
recordedTime = clock.instant(),
|
||||
isRelevant = if (isRelevant) Vault.RelevancyStatus.RELEVANT else Vault.RelevancyStatus.NOT_RELEVANT
|
||||
relevancyStatus = if (isRelevant) Vault.RelevancyStatus.RELEVANT else Vault.RelevancyStatus.NOT_RELEVANT
|
||||
)
|
||||
stateToAdd.stateRef = PersistentStateRef(stateAndRef.key)
|
||||
session.save(stateToAdd)
|
||||
@ -403,7 +405,7 @@ class NodeVaultService(
|
||||
val enrichedCriteria = QueryCriteria.VaultQueryCriteria(
|
||||
contractStateTypes = setOf(contractStateType),
|
||||
softLockingCondition = QueryCriteria.SoftLockingCondition(QueryCriteria.SoftLockingType.UNLOCKED_AND_SPECIFIED, listOf(lockId)),
|
||||
isRelevant = Vault.RelevancyStatus.RELEVANT
|
||||
relevancyStatus = Vault.RelevancyStatus.RELEVANT
|
||||
)
|
||||
val results = queryBy(contractStateType, enrichedCriteria.and(eligibleStatesQuery), sorter)
|
||||
|
||||
@ -511,7 +513,7 @@ class NodeVaultService(
|
||||
vaultState.notary,
|
||||
vaultState.lockId,
|
||||
vaultState.lockUpdateTime,
|
||||
vaultState.isRelevant))
|
||||
vaultState.relevancyStatus))
|
||||
} else {
|
||||
// TODO: improve typing of returned other results
|
||||
log.debug { "OtherResults: ${Arrays.toString(result.toArray())}" }
|
||||
|
@ -61,8 +61,8 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
|
||||
var lockId: String? = null,
|
||||
|
||||
/** Used to determine whether a state abides by the relevancy rules of the recording node */
|
||||
@Column(name = "is_relevant", nullable = false)
|
||||
var isRelevant: Vault.RelevancyStatus,
|
||||
@Column(name = "relevancy_status", nullable = false)
|
||||
var relevancyStatus: Vault.RelevancyStatus,
|
||||
|
||||
/** refers to the last time a lock was taken (reserved) or updated (released, re-reserved) */
|
||||
@Column(name = "lock_timestamp", nullable = true)
|
||||
|
@ -2,14 +2,18 @@
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
|
||||
<changeSet author="R3.Corda" id="add_is_relevant_column">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="vault_states" columnName="is_relevant"/></not></preConditions>
|
||||
<changeSet author="R3.Corda" id="add_relevancy_status_column">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<columnExists tableName="vault_states" columnName="relevancy_status"/>
|
||||
</not>
|
||||
</preConditions>
|
||||
<addColumn tableName="vault_states">
|
||||
<column name="is_relevant" type="INT"/>
|
||||
<column name="relevancy_status" type="INT"/>
|
||||
</addColumn>
|
||||
<update tableName="vault_states">
|
||||
<column name="is_relevant" valueNumeric="0"/>
|
||||
<column name="relevancy_status" valueNumeric="0"/>
|
||||
</update>
|
||||
<addNotNullConstraint tableName="vault_states" columnName="is_relevant" columnDataType="INT" />
|
||||
<addNotNullConstraint tableName="vault_states" columnName="relevancy_status" columnDataType="INT"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
|
@ -48,7 +48,7 @@ import java.math.BigDecimal
|
||||
import java.util.*
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.Executors
|
||||
import javax.persistence.*
|
||||
import javax.persistence.PersistenceException
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
@ -759,13 +759,13 @@ class NodeVaultServiceTest {
|
||||
|
||||
// Test two.
|
||||
// RelevancyStatus set to NOT_RELEVANT.
|
||||
val criteriaTwo = VaultQueryCriteria(isRelevant = Vault.RelevancyStatus.NOT_RELEVANT)
|
||||
val criteriaTwo = VaultQueryCriteria(relevancyStatus = Vault.RelevancyStatus.NOT_RELEVANT)
|
||||
val resultTwo = vaultService.queryBy<DummyState>(criteriaTwo).states.getNumbers()
|
||||
assertEquals(setOf(4, 5), resultTwo)
|
||||
|
||||
// Test three.
|
||||
// RelevancyStatus set to ALL.
|
||||
val criteriaThree = VaultQueryCriteria(isRelevant = Vault.RelevancyStatus.RELEVANT)
|
||||
val criteriaThree = VaultQueryCriteria(relevancyStatus = Vault.RelevancyStatus.RELEVANT)
|
||||
val resultThree = vaultService.queryBy<DummyState>(criteriaThree).states.getNumbers()
|
||||
assertEquals(setOf(1, 3, 6), resultThree)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user