mirror of
https://github.com/corda/corda.git
synced 2024-12-28 00:38:55 +00:00
R3NET-546: Improve the way CheckMembership operation is performed (#140)
This commit is contained in:
parent
60bde88777
commit
fad29ff1f6
@ -10,6 +10,8 @@ import net.corda.core.transactions.SignedTransaction
|
|||||||
import net.corda.core.transactions.TransactionBuilder
|
import net.corda.core.transactions.TransactionBuilder
|
||||||
import net.corda.core.utilities.ProgressTracker
|
import net.corda.core.utilities.ProgressTracker
|
||||||
import net.corda.sample.businessnetwork.membership.MembershipAware
|
import net.corda.sample.businessnetwork.membership.MembershipAware
|
||||||
|
import net.corda.sample.businessnetwork.membership.CheckMembershipFlow
|
||||||
|
import net.corda.sample.businessnetwork.membership.CheckMembershipResult
|
||||||
import kotlin.reflect.jvm.jvmName
|
import kotlin.reflect.jvm.jvmName
|
||||||
|
|
||||||
@InitiatingFlow
|
@InitiatingFlow
|
||||||
@ -28,15 +30,12 @@ class IOUFlow(val iouValue: Int,
|
|||||||
/** The flow logic is encapsulated within the call() method. */
|
/** The flow logic is encapsulated within the call() method. */
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call(): SignedTransaction {
|
override fun call(): SignedTransaction {
|
||||||
|
// Prior to creating any state, check on our side whether [otherParty] belongs to desired membership list.
|
||||||
// Check whether the other party belongs to the membership list important for us.
|
// Also obtain consent from [otherParty] to borrow from us.
|
||||||
otherParty.checkMembership(allowedMembershipName, this)
|
|
||||||
|
|
||||||
// Prior to creating any state - obtain consent from [otherParty] to borrow from us.
|
|
||||||
// This is done early enough in the flow such that if the other party rejects - do not do any unnecessary processing in this flow.
|
// This is done early enough in the flow such that if the other party rejects - do not do any unnecessary processing in this flow.
|
||||||
// Even if this is not done, later on upon signatures collection phase membership will be checked on the other side and
|
// Even if this is not done, later on upon signatures collection phase membership will be checked on the other side and
|
||||||
// transaction rejected if this doesn't hold. See [IOUFlowResponder] for more information.
|
// transaction rejected if this doesn't hold. See [IOUFlowResponder] for more information.
|
||||||
otherParty.checkSharesSameMembershipWithUs(allowedMembershipName, this)
|
check(subFlow(CheckMembershipFlow(otherParty, allowedMembershipName)) == CheckMembershipResult.PASS)
|
||||||
|
|
||||||
// We retrieve the notary identity from the network map.
|
// We retrieve the notary identity from the network map.
|
||||||
val notary = serviceHub.networkMapCache.notaryIdentities[0]
|
val notary = serviceHub.networkMapCache.notaryIdentities[0]
|
@ -7,13 +7,14 @@ import net.corda.core.flows.FlowSession
|
|||||||
import net.corda.core.flows.InitiatedBy
|
import net.corda.core.flows.InitiatedBy
|
||||||
import net.corda.core.flows.SignTransactionFlow
|
import net.corda.core.flows.SignTransactionFlow
|
||||||
import net.corda.core.transactions.SignedTransaction
|
import net.corda.core.transactions.SignedTransaction
|
||||||
import net.corda.sample.businessnetwork.membership.CheckMembershipFlow
|
import net.corda.sample.businessnetwork.membership.MembershipAware
|
||||||
|
|
||||||
@InitiatedBy(IOUFlow::class)
|
@InitiatedBy(IOUFlow::class)
|
||||||
class IOUFlowResponder(val otherPartySession: FlowSession) : FlowLogic<Unit>() {
|
class IOUFlowResponder(val otherPartySession: FlowSession) : FlowLogic<Unit>(), MembershipAware {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call() {
|
override fun call() {
|
||||||
subFlow(CheckMembershipFlow(IOUFlow.allowedMembershipName, otherPartySession.counterparty))
|
|
||||||
|
otherPartySession.counterparty.checkMembership(IOUFlow.allowedMembershipName, this)
|
||||||
|
|
||||||
subFlow(object : SignTransactionFlow(otherPartySession, SignTransactionFlow.tracker()) {
|
subFlow(object : SignTransactionFlow(otherPartySession, SignTransactionFlow.tracker()) {
|
||||||
override fun checkTransaction(stx: SignedTransaction) = requireThat {
|
override fun checkTransaction(stx: SignedTransaction) = requireThat {
|
@ -1,11 +1,38 @@
|
|||||||
package net.corda.sample.businessnetwork.membership
|
package net.corda.sample.businessnetwork.membership
|
||||||
|
|
||||||
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.identity.AbstractParty
|
import net.corda.core.flows.FlowSession
|
||||||
|
import net.corda.core.flows.InitiatedBy
|
||||||
|
import net.corda.core.flows.InitiatingFlow
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
|
import net.corda.core.identity.Party
|
||||||
|
import net.corda.core.serialization.CordaSerializable
|
||||||
|
import net.corda.core.utilities.unwrap
|
||||||
|
|
||||||
class CheckMembershipFlow(private val membershipName: CordaX500Name, private val counterParty: AbstractParty) : FlowLogic<Unit>(), MembershipAware {
|
@CordaSerializable
|
||||||
|
enum class CheckMembershipResult {
|
||||||
|
PASS,
|
||||||
|
FAIL
|
||||||
|
}
|
||||||
|
|
||||||
|
@InitiatingFlow
|
||||||
|
class CheckMembershipFlow(private val otherParty: Party, private val membershipName: CordaX500Name) : FlowLogic<CheckMembershipResult>(), MembershipAware {
|
||||||
|
@Suspendable
|
||||||
|
override fun call(): CheckMembershipResult {
|
||||||
|
otherParty.checkMembership(membershipName, this)
|
||||||
|
// This will trigger CounterpartyCheckMembershipFlow
|
||||||
|
val untrustworthyData = initiateFlow(otherParty).sendAndReceive<CheckMembershipResult>(membershipName)
|
||||||
|
return untrustworthyData.unwrap { it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@InitiatedBy(CheckMembershipFlow::class)
|
||||||
|
class CounterpartyCheckMembershipFlow(private val otherPartySession: FlowSession) : FlowLogic<Unit>(), MembershipAware {
|
||||||
|
@Suspendable
|
||||||
override fun call() {
|
override fun call() {
|
||||||
counterParty.checkMembership(membershipName, this)
|
val membershipName = otherPartySession.receive<CordaX500Name>().unwrap { it }
|
||||||
|
otherPartySession.counterparty.checkMembership(membershipName, this)
|
||||||
|
otherPartySession.send(CheckMembershipResult.PASS)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,7 +4,6 @@ import net.corda.core.flows.FlowException
|
|||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.identity.AbstractParty
|
import net.corda.core.identity.AbstractParty
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.identity.Party
|
|
||||||
import net.corda.core.node.ServiceHub
|
import net.corda.core.node.ServiceHub
|
||||||
import net.corda.sample.businessnetwork.membership.internal.MembershipListProvider
|
import net.corda.sample.businessnetwork.membership.internal.MembershipListProvider
|
||||||
|
|
||||||
@ -22,10 +21,6 @@ interface MembershipAware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getMembershipList(listName: CordaX500Name, serviceHub: ServiceHub): MembershipList = MembershipListProvider.obtainMembershipList(listName, serviceHub.networkMapCache)
|
fun getMembershipList(listName: CordaX500Name, serviceHub: ServiceHub): MembershipList = MembershipListProvider.obtainMembershipList(listName, serviceHub.networkMapCache)
|
||||||
|
|
||||||
fun <T> Party.checkSharesSameMembershipWithUs(membershipName: CordaX500Name, initiatorFlow: FlowLogic<T>) {
|
|
||||||
initiatorFlow.stateMachine.initiateFlow(this, CheckMembershipFlow(membershipName, initiatorFlow.ourIdentity))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MembershipViolationException(msg: String) : FlowException(msg)
|
class MembershipViolationException(msg: String) : FlowException(msg)
|
Loading…
Reference in New Issue
Block a user