Unable to initiate a flow session with another node from a ScheduledFlow

放肆的年华 提交于 2019-12-11 14:39:46

问题


I am trying to initiate a flow session with another node from a ScheduledFlow. Below is the Scheduledstate definiton:

data class State(val a: Party,
                         val b: Party,
                         val instant: Instant,
                          val status: Status,
                          override val linearId: UniqueIdentifier = UniqueIdentifier(),
                          override val participants: List<AbstractParty> = listOf(a, b))
: LinearState, SchedulableState {

private val scheduledTime = instant
override fun nextScheduledActivity(thisStateRef: StateRef, flowLogicRefFactory: FlowLogicRefFactory): ScheduledActivity? {
    if (status != Status.COMPLETED) {
        return null
    } else {
        return ScheduledActivity(flowLogicRefFactory.create("com.example.flows.StartFlow", thisStateRef), scheduledTime)
    }
}}

Below is the StartFlow definiton:

@InitiatingFlow
@SchedulableFlow
class StartFlow(val ref: StateRef): FlowLogic<SignedTransaction?>(){

    @Suspendable
    override fun call(): SignedTransaction? {
        val notary = serviceHub.networkMapCache.notaryIdentities[0]
        val stateAndRef = serviceHub.loadState(stateRef = ref)
        val state = stateAndRef.data as State
        if (state.status != State.COMPLETED) {
            throw IllegalArgumentException("Cannot initiate transfer of ownership")
        }

        // Role decider:
        val parties = state.participants.sortedBy { it.owningKey.toBase58String() }
        if (ourIdentity == parties[0]) {
            val tx = TransactionBuilder(notary = notary)

            // add input states
            tx.addInputState(stateAndRef)

            // add output states
            tx.addOutputState(state.copy(status = Status.TRANSFERRED), ContractA.CONTRACT_ID)
            val command = Command(ContractA.Commands.Command1(), listOf(state.a.owningKey, state.b.owningKey))
            tx.addCommand(command)

            tx.verify(serviceHub)

            val partSignedTx = serviceHub.signInitialTransaction(tx)
            val counterparty = serviceHub.identityService.wellKnownPartyFromAnonymous(parties[1]) ?: throw IllegalStateException("Cannot resolve responding party")
            val counterPartySession = initiateFlow(counterparty)
            val fullySignedTx = subFlow(CollectSignaturesFlow(partSignedTx, setOf(counterPartySession)))

            return subFlow(FinalityFlow(fullySignedTx))
        }
        return null
    }
}

while testing the above flow, State object is created as follows:

State(a, b, Instant.now().plus(10), Status.COMPLETED)

StartFlow is not able to initiate the session with counter party and the code gets stuck there.

If the State is constructed as

State(a, b, Instant.now(), Status.COMPLETED)

The StartFlow is able to initiate session with counterparty and everything works fine.

What could be the issue here?


回答1:


As Nitesh reported, the condition check was incorrect for the deciding role. ourIdentity == parties[0] should have been ourIdentity.owingkey == parties[0].owningkey.

This is because parties[0] is of type AbstractParty. ourIdentity is of type Party. AbstractParty overrides equals as follows:

override fun equals(other: Any?): Boolean = 
    other === this || 
    other is AbstractParty && other.owningKey == owningKey

Thus the two objects were not considered equal.



来源:https://stackoverflow.com/questions/53011893/unable-to-initiate-a-flow-session-with-another-node-from-a-scheduledflow

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!