mirror of
https://github.com/corda/corda.git
synced 2024-12-20 21:43:14 +00:00
Removed is relevant from LinearState (#1294)
This commit is contained in:
parent
cdea1665cf
commit
9bd4342039
@ -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<PublicKey>): Boolean
|
||||
}
|
||||
// DOCEND 2
|
||||
|
||||
|
@ -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
|
||||
------------
|
||||
|
||||
|
@ -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<Party> get() = listOf(source, counterparty)
|
||||
override val participants: List<AbstractParty> get() = parties
|
||||
|
||||
override fun isRelevant(ourKeys: Set<PublicKey>): Boolean {
|
||||
return participants.any { it.owningKey.containsAny(ourKeys) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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<WireTransaction>) {
|
||||
val ourKeys = services.keyManagementService.keys
|
||||
fun makeUpdate(tx: WireTransaction): Vault.Update<ContractState> {
|
||||
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<ContractState>(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<ContractState>(it.data) }
|
||||
@ -391,9 +387,11 @@ class NodeVaultService(private val services: ServiceHub) : SingletonSerializeAsT
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
internal fun isRelevant(state: ContractState, ourKeys: Set<PublicKey>) = 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<PublicKey>): Boolean {
|
||||
val keysToCheck = when (state) {
|
||||
is OwnableState -> listOf(state.owner.owningKey)
|
||||
else -> state.participants.map { it.owningKey }
|
||||
}
|
||||
return keysToCheck.any { it in myKeys }
|
||||
}
|
||||
}
|
||||
|
@ -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<AbstractParty>
|
||||
get() = throw UnsupportedOperationException()
|
||||
get() = listOf(myIdentity)
|
||||
|
||||
override val linearId = UniqueIdentifier()
|
||||
|
||||
override fun isRelevant(ourKeys: Set<PublicKey>): 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)
|
||||
|
@ -58,10 +58,6 @@ class ScheduledFlowTests {
|
||||
}
|
||||
|
||||
override val participants: List<AbstractParty> = listOf(source, destination)
|
||||
|
||||
override fun isRelevant(ourKeys: Set<PublicKey>): Boolean {
|
||||
return participants.any { it.owningKey.containsAny(ourKeys) }
|
||||
}
|
||||
}
|
||||
|
||||
class InsertInitialStateFlow(val destination: Party) : FlowLogic<Unit>() {
|
||||
|
@ -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
|
||||
|
@ -618,10 +618,6 @@ class InterestRateSwap : Contract {
|
||||
override val participants: List<AbstractParty>
|
||||
get() = listOf(fixedLeg.fixedRatePayer, floatingLeg.floatingRatePayer)
|
||||
|
||||
override fun isRelevant(ourKeys: Set<PublicKey>): 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
|
||||
|
||||
|
@ -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<AbstractParty> get() = listOf(buyer, seller)
|
||||
|
||||
override fun isRelevant(ourKeys: Set<PublicKey>): 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 }))
|
||||
|
@ -37,10 +37,6 @@ data class PortfolioState(val portfolio: List<StateRef>,
|
||||
return ScheduledActivity(flow, LocalDate.now().plus(1, ChronoUnit.DAYS).atStartOfDay().toInstant(ZoneOffset.UTC))
|
||||
}
|
||||
|
||||
override fun isRelevant(ourKeys: Set<PublicKey>): 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 }))
|
||||
}
|
||||
|
@ -26,10 +26,6 @@ class DummyDealContract : Contract {
|
||||
participants: List<AbstractParty> = listOf(),
|
||||
ref: String) : this(contract, participants, UniqueIdentifier(ref))
|
||||
|
||||
override fun isRelevant(ourKeys: Set<PublicKey>): Boolean {
|
||||
return participants.any { it.owningKey.containsAny(ourKeys) }
|
||||
}
|
||||
|
||||
override fun generateAgreement(notary: Party): TransactionBuilder {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
|
@ -39,10 +39,6 @@ class DummyLinearContract : Contract {
|
||||
val linearBoolean: Boolean = true,
|
||||
val nonce: SecureHash = SecureHash.randomSHA256()) : LinearState, QueryableState {
|
||||
|
||||
override fun isRelevant(ourKeys: Set<java.security.PublicKey>): Boolean {
|
||||
return participants.any { it.owningKey.containsAny(ourKeys) }
|
||||
}
|
||||
|
||||
override fun supportedSchemas(): Iterable<MappedSchema> = listOf(DummyLinearStateSchemaV1, DummyLinearStateSchemaV2)
|
||||
|
||||
override fun generateMappedObject(schema: MappedSchema): PersistentState {
|
||||
|
Loading…
Reference in New Issue
Block a user