首页 > 解决方案 > CollectSignaturesFlow 中的流异常

问题描述

我正在创建一个流程以从另一方的 CollectSignaturesFlow 中获取签名,并且我在日志中面临以下问题。

@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()));
    }
}

部署和执行后,流程停止,给我以​​下错误:

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:?]

我相信我正在通过所需的流程会话,我仍然得到这个。关于如何解决这个问题的任何想法?

编辑 1:当我使用下面的代码将 flowsession 替换为多个会话并执行它时,流程发生了变化,甚至在日志中什么也没写。我想知道以下是否是获取签名的正确方法。

 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()));

BGState 中的 getParties() 代码:

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

BGState 定义:

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);
}

}

标签: corda

解决方案


FlowSession传递给的 s 列表CollectSignaturesFlow必须与交易所需的签名者完全对应。

在这种情况下,监管机构没有FlowSession通过,监管机构是必需的签名者之一。


推荐阅读