From 9bd4342039ecf20f24ec4a52808f9dc8204bf769 Mon Sep 17 00:00:00 2001 From: Patrick Kuo Date: Wed, 30 Aug 2017 16:26:34 +0100 Subject: [PATCH] Removed is relevant from LinearState (#1294) --- .../net/corda/core/contracts/Structures.kt | 5 ----- docs/source/api-vault-query.rst | 2 +- docs/source/changelog.rst | 4 +++- .../docs/WorkflowTransactionBuildTutorial.kt | 6 ----- .../node/services/vault/NodeVaultService.kt | 22 +++++++++---------- .../events/NodeSchedulerServiceTest.kt | 9 ++++---- .../services/events/ScheduledFlowTests.kt | 4 ---- .../services/vault/NodeVaultServiceTest.kt | 9 +++++--- .../main/kotlin/net/corda/irs/contract/IRS.kt | 4 ---- .../net/corda/vega/contracts/IRSState.kt | 4 ---- .../corda/vega/contracts/PortfolioState.kt | 4 ---- .../testing/contracts/DummyDealContract.kt | 4 ---- .../testing/contracts/DummyLinearContract.kt | 4 ---- 13 files changed, 24 insertions(+), 57 deletions(-) diff --git a/core/src/main/kotlin/net/corda/core/contracts/Structures.kt b/core/src/main/kotlin/net/corda/core/contracts/Structures.kt index c54a779595..6930c209aa 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/Structures.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/Structures.kt @@ -219,11 +219,6 @@ interface LinearState : ContractState { * except at issuance/termination. */ val linearId: UniqueIdentifier - - /** - * True if this should be tracked by our vault(s). - */ - fun isRelevant(ourKeys: Set): Boolean } // DOCEND 2 diff --git a/docs/source/api-vault-query.rst b/docs/source/api-vault-query.rst index 32626ecb0a..c7fd9948da 100644 --- a/docs/source/api-vault-query.rst +++ b/docs/source/api-vault-query.rst @@ -395,4 +395,4 @@ The Corda Tutorials provide examples satisfying these additional Use Cases: .. _JPQL: http://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#hql .. _JPA: https://docs.spring.io/spring-data/jpa/docs/current/reference/html - + diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index cd88037e0a..2ce4b0db3f 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -34,7 +34,6 @@ UNRELEASED must use ``SendTransactionFlow`` at the correct place. There is also ``ReceiveStateAndRefFlow`` and ``SendStateAndRefFlow`` for dealing with ``StateAndRef``s. - * Vault query soft locking enhancements and deprecations * removed original ``VaultService`` ``softLockedStates` query mechanism. * introduced improved ``SoftLockingCondition`` filterable attribute in ``VaultQueryCriteria`` to enable specification @@ -68,6 +67,9 @@ UNRELEASED * Moved ``:finance`` gradle project files into a ``net.corda.finance`` package namespace. This may require adjusting imports of Cash flow references and also of ``StartFlow`` permission in ``gradle.build`` files. +* Removed the concept of relevancy from ``LinearState``. The ``ContractState``'s relevancy to the vault can be determined + by the flow context, the vault will process any transaction from a flow which is not derived from transaction resolution verification. + Milestone 14 ------------ diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt index daa6d6e149..1a95f67464 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt @@ -3,7 +3,6 @@ package net.corda.docs import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.* import net.corda.core.crypto.TransactionSignature -import net.corda.core.crypto.containsAny import net.corda.core.flows.FinalityFlow import net.corda.core.flows.FlowLogic import net.corda.core.flows.InitiatedBy @@ -18,7 +17,6 @@ import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.seconds import net.corda.core.utilities.unwrap -import java.security.PublicKey // Minimal state model of a manual approval process @CordaSerializable @@ -51,10 +49,6 @@ data class TradeApprovalContract(private val blank: Void? = null) : Contract { val parties: List get() = listOf(source, counterparty) override val participants: List get() = parties - - override fun isRelevant(ourKeys: Set): Boolean { - return participants.any { it.owningKey.containsAny(ourKeys) } - } } /** diff --git a/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt b/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt index 64fb9c81fa..023e87a1f7 100644 --- a/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt +++ b/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt @@ -4,7 +4,6 @@ import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.strands.Strand import net.corda.core.contracts.* import net.corda.core.crypto.SecureHash -import net.corda.core.crypto.containsAny import net.corda.core.internal.ThreadBox import net.corda.core.internal.VisibleForTesting import net.corda.core.internal.tee @@ -144,10 +143,10 @@ class NodeVaultService(private val services: ServiceHub) : SingletonSerializeAsT } private fun notifyRegular(txns: Iterable) { - val ourKeys = services.keyManagementService.keys fun makeUpdate(tx: WireTransaction): Vault.Update { + val myKeys = services.keyManagementService.filterMyKeys(tx.outputs.flatMap { it.data.participants.map { it.owningKey } }) val ourNewStates = tx.outputs. - filter { isRelevant(it.data, ourKeys) }. + filter { isRelevant(it.data, myKeys.toSet()) }. map { tx.outRef(it.data) } // Retrieve all unconsumed states for this transaction's inputs @@ -173,13 +172,10 @@ class NodeVaultService(private val services: ServiceHub) : SingletonSerializeAsT // We also can't do filtering beforehand, since output encumbrance pointers get recalculated based on // input positions val ltx = tx.resolve(services, emptyList()) - + val myKeys = services.keyManagementService.filterMyKeys(ltx.outputs.flatMap { it.data.participants.map { it.owningKey } }) val (consumedStateAndRefs, producedStates) = ltx.inputs. zip(ltx.outputs). - filter { - (_, output) -> - isRelevant(output.data, ourKeys) - }. + filter { (_, output) -> isRelevant(output.data, myKeys.toSet()) }. unzip() val producedStateAndRefs = producedStates.map { ltx.outRef(it.data) } @@ -391,9 +387,11 @@ class NodeVaultService(private val services: ServiceHub) : SingletonSerializeAsT } @VisibleForTesting - internal fun isRelevant(state: ContractState, ourKeys: Set) = when (state) { - is OwnableState -> state.owner.owningKey.containsAny(ourKeys) - is LinearState -> state.isRelevant(ourKeys) - else -> ourKeys.intersect(state.participants.map { it.owningKey }).isNotEmpty() + internal fun isRelevant(state: ContractState, myKeys: Set): Boolean { + val keysToCheck = when (state) { + is OwnableState -> listOf(state.owner.owningKey) + else -> state.participants.map { it.owningKey } + } + return keysToCheck.any { it in myKeys } } } diff --git a/node/src/test/kotlin/net/corda/node/services/events/NodeSchedulerServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/events/NodeSchedulerServiceTest.kt index deaf74f15d..0280afd686 100644 --- a/node/src/test/kotlin/net/corda/node/services/events/NodeSchedulerServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/events/NodeSchedulerServiceTest.kt @@ -5,6 +5,7 @@ import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogicRef import net.corda.core.flows.FlowLogicRefFactory import net.corda.core.identity.AbstractParty +import net.corda.core.identity.Party import net.corda.core.node.ServiceHub import net.corda.core.node.services.VaultService import net.corda.core.serialization.SingletonSerializeAsToken @@ -120,14 +121,12 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() { resetTestSerialization() } - class TestState(val flowLogicRef: FlowLogicRef, val instant: Instant) : LinearState, SchedulableState { + class TestState(val flowLogicRef: FlowLogicRef, val instant: Instant, private val myIdentity: Party) : LinearState, SchedulableState { override val participants: List - get() = throw UnsupportedOperationException() + get() = listOf(myIdentity) override val linearId = UniqueIdentifier() - override fun isRelevant(ourKeys: Set): Boolean = true - override fun nextScheduledActivity(thisStateRef: StateRef, flowLogicRefFactory: FlowLogicRefFactory): ScheduledActivity? { return ScheduledActivity(flowLogicRef, instant) } @@ -279,7 +278,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() { database.transaction { apply { val freshKey = services.keyManagementService.freshKey() - val state = TestState(FlowLogicRefFactoryImpl.createForRPC(TestFlowLogic::class.java, increment), instant) + val state = TestState(FlowLogicRefFactoryImpl.createForRPC(TestFlowLogic::class.java, increment), instant, services.myInfo.legalIdentity) val builder = TransactionBuilder(null).apply { addOutputState(state, DUMMY_NOTARY) addCommand(Command(), freshKey) diff --git a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt index 5988b575db..6b1035adf1 100644 --- a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt @@ -58,10 +58,6 @@ class ScheduledFlowTests { } override val participants: List = listOf(source, destination) - - override fun isRelevant(ourKeys: Set): Boolean { - return participants.any { it.owningKey.containsAny(ourKeys) } - } } class InsertInitialStateFlow(val destination: Party) : FlowLogic() { diff --git a/node/src/test/kotlin/net/corda/node/services/vault/NodeVaultServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/vault/NodeVaultServiceTest.kt index c7a762117e..cc839addf4 100644 --- a/node/src/test/kotlin/net/corda/node/services/vault/NodeVaultServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/vault/NodeVaultServiceTest.kt @@ -476,15 +476,18 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() { val service = (services.vaultService as NodeVaultService) val amount = Amount(1000, Issued(BOC.ref(1), GBP)) val wellKnownCash = Cash.State(amount, services.myInfo.legalIdentity) - assertTrue { service.isRelevant(wellKnownCash, services.keyManagementService.keys) } + val myKeys = services.keyManagementService.filterMyKeys(listOf(wellKnownCash.owner.owningKey)) + assertTrue { service.isRelevant(wellKnownCash, myKeys.toSet()) } val anonymousIdentity = services.keyManagementService.freshKeyAndCert(services.myInfo.legalIdentityAndCert, false) val anonymousCash = Cash.State(amount, anonymousIdentity.party) - assertTrue { service.isRelevant(anonymousCash, services.keyManagementService.keys) } + val anonymousKeys = services.keyManagementService.filterMyKeys(listOf(anonymousCash.owner.owningKey)) + assertTrue { service.isRelevant(anonymousCash, anonymousKeys.toSet()) } val thirdPartyIdentity = AnonymousParty(generateKeyPair().public) val thirdPartyCash = Cash.State(amount, thirdPartyIdentity) - assertFalse { service.isRelevant(thirdPartyCash, services.keyManagementService.keys) } + val thirdPartyKeys = services.keyManagementService.filterMyKeys(listOf(thirdPartyCash.owner.owningKey)) + assertFalse { service.isRelevant(thirdPartyCash, thirdPartyKeys.toSet()) } } // TODO: Unit test linear state relevancy checks diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt index aa901cfe6b..e7053be51f 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt @@ -618,10 +618,6 @@ class InterestRateSwap : Contract { override val participants: List get() = listOf(fixedLeg.fixedRatePayer, floatingLeg.floatingRatePayer) - override fun isRelevant(ourKeys: Set): Boolean { - return fixedLeg.fixedRatePayer.owningKey.containsAny(ourKeys) || floatingLeg.floatingRatePayer.owningKey.containsAny(ourKeys) - } - override fun nextScheduledActivity(thisStateRef: StateRef, flowLogicRefFactory: FlowLogicRefFactory): ScheduledActivity? { val nextFixingOf = nextFixingOf() ?: return null diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt index a7b02c55a0..db1eff6755 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt @@ -22,10 +22,6 @@ data class IRSState(val swap: SwapData, val ref: String get() = linearId.externalId!! // Same as the constructor for UniqueIdentified override val participants: List get() = listOf(buyer, seller) - override fun isRelevant(ourKeys: Set): Boolean { - return participants.flatMap { it.owningKey.keys }.intersect(ourKeys).isNotEmpty() - } - override fun generateAgreement(notary: Party): TransactionBuilder { val state = IRSState(swap, buyer, seller, OGTrade()) return TransactionBuilder(notary).withItems(state, Command(OGTrade.Commands.Agree(), participants.map { it.owningKey })) diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioState.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioState.kt index ee351737c5..02b1367d14 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioState.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioState.kt @@ -37,10 +37,6 @@ data class PortfolioState(val portfolio: List, return ScheduledActivity(flow, LocalDate.now().plus(1, ChronoUnit.DAYS).atStartOfDay().toInstant(ZoneOffset.UTC)) } - override fun isRelevant(ourKeys: Set): Boolean { - return participants.flatMap { it.owningKey.keys }.intersect(ourKeys).isNotEmpty() - } - override fun generateAgreement(notary: Party): TransactionBuilder { return TransactionBuilder(notary).withItems(copy(), Command(PortfolioSwap.Commands.Agree(), participants.map { it.owningKey })) } diff --git a/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyDealContract.kt b/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyDealContract.kt index 1ac197efb7..bd0e41b08f 100644 --- a/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyDealContract.kt +++ b/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyDealContract.kt @@ -26,10 +26,6 @@ class DummyDealContract : Contract { participants: List = listOf(), ref: String) : this(contract, participants, UniqueIdentifier(ref)) - override fun isRelevant(ourKeys: Set): Boolean { - return participants.any { it.owningKey.containsAny(ourKeys) } - } - override fun generateAgreement(notary: Party): TransactionBuilder { throw UnsupportedOperationException("not implemented") } diff --git a/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyLinearContract.kt b/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyLinearContract.kt index c2bb95fd09..408fefffd3 100644 --- a/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyLinearContract.kt +++ b/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyLinearContract.kt @@ -39,10 +39,6 @@ class DummyLinearContract : Contract { val linearBoolean: Boolean = true, val nonce: SecureHash = SecureHash.randomSHA256()) : LinearState, QueryableState { - override fun isRelevant(ourKeys: Set): Boolean { - return participants.any { it.owningKey.containsAny(ourKeys) } - } - override fun supportedSchemas(): Iterable = listOf(DummyLinearStateSchemaV1, DummyLinearStateSchemaV2) override fun generateMappedObject(schema: MappedSchema): PersistentState {