Flow Exception in CollectSignaturesFlow

谁都会走 提交于 2019-12-24 02:17:44

问题


I am creating a flow to fetch signatures from CollectSignaturesFlow of other party and I am facing the below issue in log.

@InitiatingFlow
@StartableByRPC
public static class BGInitiator extends FlowLogic<SignedTransaction> {

    private final Party manufacturer;
    private final Party regulator;
    private final String bgData;

    public BGInitiator(Party manufacturer,Party regulator, String bgData) {
        this.manufacturer = manufacturer;
        this.regulator = regulator;
        this.bgData = bgData;
    }
    private final Step GENERATING_TRANSACTION = new Step("Generating transaction based on YO.");
    private final Step BUILDING_TRANSACTION = new Step("Verifying contract constraints.");
    private final Step SIGNING_TRANSACTION = new Step("Signing transaction with our private key.");
    private final Step GATHERING_SIGS = new Step("Gathering the counterparty's signature.") {
        @Override
        public ProgressTracker childProgressTracker() {
            return CollectSignaturesFlow.Companion.tracker();
        }
    };
    private final Step FINALISING_TRANSACTION = new Step("Obtaining notary signature and recording transaction.") {
        @Override
        public ProgressTracker childProgressTracker() {
            return FinalityFlow.Companion.tracker();
        }
    };

    private final ProgressTracker progressTracker = new ProgressTracker(
            GENERATING_TRANSACTION,
            BUILDING_TRANSACTION,
            SIGNING_TRANSACTION,
            GATHERING_SIGS,
            FINALISING_TRANSACTION
    );

    @Override
    public ProgressTracker getProgressTracker() {
        return progressTracker;
    }

    @Suspendable
    @Override
    public SignedTransaction call() throws FlowException {
        progressTracker.setCurrentStep(GENERATING_TRANSACTION);

        Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
        BGState bgState = new BGState(getOurIdentity(),manufacturer,regulator,bgData);

        progressTracker.setCurrentStep(BUILDING_TRANSACTION);
        final List<PublicKey> requiredSigners = bgState.getParticipantKeys();
        final List<Party> parties = bgState.getParties();
         final PublicKey me = bgState.getSeller().getOwningKey();


        final TransactionBuilder tb = new TransactionBuilder(notary)
                .addOutputState(bgState,BGContract.BG_CONTRACT_ID)
                .addCommand(new BGContract.Commands.Send(),requiredSigners);

        progressTracker.setCurrentStep(SIGNING_TRANSACTION);
        final SignedTransaction ptx = getServiceHub().signInitialTransaction(tb,me);

        progressTracker.setCurrentStep(GATHERING_SIGS);



        FlowSession manufacturerflow = initiateFlow(manufacturer);
        final SignedTransaction stx = subFlow(new CollectSignaturesFlow(ptx,ImmutableSet.of(manufacturerflow),ImmutableList.of(me),GATHERING_SIGS.childProgressTracker()));

        progressTracker.setCurrentStep(FINALISING_TRANSACTION);
        return subFlow(new FinalityFlow(stx,FINALISING_TRANSACTION.childProgressTracker()));
    }
}

After deploying and executing, the flow stops, giving me the following error:

java.lang.IllegalArgumentException: The Initiator of CollectSignaturesFlow must pass in exactly the sessions required to sign the transaction.
at net.corda.core.flows.CollectSignaturesFlow.call(CollectSignaturesFlow.kt:108) ~[corda-core-2.0.0.jar:?]
at net.corda.core.flows.CollectSignaturesFlow.call(CollectSignaturesFlow.kt:64) ~[corda-core-2.0.0.jar:?]
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:243) ~[corda-core-2.0.0.jar:?]
at com.example.flow.BGFlow$BGInitiator.call(BGFlow.java:107) ~[java-source-0.1.jar:?]

I believe I am passing the required flow session and I am still getting this. Any ideas on how to solve this?

Edit 1: when I replace the flowsession to multiple sessions using the code below and executing it, the flow struck and even wrote nothing in logs. I would like to know whether the following is the correct way to fetch signatures.

 List<FlowSession> flowSessions = parties.stream().map(a -> initiateFlow(a)).collect(Collectors.toList());
        final SignedTransaction stx = subFlow(new CollectSignaturesFlow(ptx,flowSessions,ImmutableList.of(me),GATHERING_SIGS.childProgressTracker()));

The getParties() code in BGState:

public List<Party> getParties(){
    return Arrays.asList(manufacturer,regulator);
}

The BGState Definition:

public class BGState implements LinearState,QueryableState {

private final Party seller;
private final Party manufacturer;
private final Party regulator;
private final String senderToReceiverInformation;
private final UniqueIdentifier linearId;



public BGState(Party seller, Party manufacturer,Party regulator,String senderToReceiverInformation) {
    this.seller = seller;
    this. manufacturer= manufacturer;
    this.regulator = regulator;
    this.senderToReceiverInformation = senderToReceiverInformation;
    this.linearId = new UniqueIdentifier();
}


public Party getSeller() {
    return seller;
}

public Party getManufacturer() {
    return manufacturer;
}

public Party getRegulator() {
    return regulator;
}



@NotNull
@Override
public UniqueIdentifier getLinearId() {
    return linearId;
}

@NotNull
@Override
public PersistentState generateMappedObject(MappedSchema schema) {
    if (schema instanceof BGSchema) {
        return new BGSchema.Bg760(
                this.seller,
                this.manufacturer,
                this.regulator,
                this.senderToReceiverInformation,
                this.linearId
        );
    } else {
        throw new IllegalArgumentException("Unrecognised schema $schema");
    }
}

@NotNull
@Override
public Iterable<MappedSchema> supportedSchemas() {
    return ImmutableList.of(new BGSchema());
}

@NotNull
@Override
public List<AbstractParty> getParticipants() {
    return Arrays.asList(seller,manufacturer,regulator);
}
public List<PublicKey> getParticipantKeys(){
    return  getParticipants().stream().map(AbstractParty :: getOwningKey).collect(Collectors.toList());
}
public List<Party> getParties(){
    return Arrays.asList(manufacturer,regulator);
}

}


回答1:


The list of FlowSessions passed to CollectSignaturesFlow must correspond exactly to the transaction's required signers.

In this case, no FlowSession was passed for the regulator, who is one of the required signers.



来源:https://stackoverflow.com/questions/51064153/flow-exception-in-collectsignaturesflow

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