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.utilities.ProgressTracker
|
||||
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
|
||||
|
||||
@InitiatingFlow
|
||||
@ -28,15 +30,12 @@ class IOUFlow(val iouValue: Int,
|
||||
/** The flow logic is encapsulated within the call() method. */
|
||||
@Suspendable
|
||||
override fun call(): SignedTransaction {
|
||||
|
||||
// Check whether the other party belongs to the membership list important for us.
|
||||
otherParty.checkMembership(allowedMembershipName, this)
|
||||
|
||||
// Prior to creating any state - obtain consent from [otherParty] to borrow from us.
|
||||
// Prior to creating any state, check on our side whether [otherParty] belongs to desired membership list.
|
||||
// Also 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.
|
||||
// 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.
|
||||
otherParty.checkSharesSameMembershipWithUs(allowedMembershipName, this)
|
||||
check(subFlow(CheckMembershipFlow(otherParty, allowedMembershipName)) == CheckMembershipResult.PASS)
|
||||
|
||||
// We retrieve the notary identity from the network map.
|
||||
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.SignTransactionFlow
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.sample.businessnetwork.membership.CheckMembershipFlow
|
||||
import net.corda.sample.businessnetwork.membership.MembershipAware
|
||||
|
||||
@InitiatedBy(IOUFlow::class)
|
||||
class IOUFlowResponder(val otherPartySession: FlowSession) : FlowLogic<Unit>() {
|
||||
class IOUFlowResponder(val otherPartySession: FlowSession) : FlowLogic<Unit>(), MembershipAware {
|
||||
@Suspendable
|
||||
override fun call() {
|
||||
subFlow(CheckMembershipFlow(IOUFlow.allowedMembershipName, otherPartySession.counterparty))
|
||||
|
||||
otherPartySession.counterparty.checkMembership(IOUFlow.allowedMembershipName, this)
|
||||
|
||||
subFlow(object : SignTransactionFlow(otherPartySession, SignTransactionFlow.tracker()) {
|
||||
override fun checkTransaction(stx: SignedTransaction) = requireThat {
|
@ -1,11 +1,38 @@
|
||||
package net.corda.sample.businessnetwork.membership
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
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.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 {
|
||||
override fun call() {
|
||||
counterParty.checkMembership(membershipName, this)
|
||||
@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() {
|
||||
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.identity.AbstractParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.ServiceHub
|
||||
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 <T> Party.checkSharesSameMembershipWithUs(membershipName: CordaX500Name, initiatorFlow: FlowLogic<T>) {
|
||||
initiatorFlow.stateMachine.initiateFlow(this, CheckMembershipFlow(membershipName, initiatorFlow.ourIdentity))
|
||||
}
|
||||
}
|
||||
|
||||
class MembershipViolationException(msg: String) : FlowException(msg)
|
Loading…
Reference in New Issue
Block a user