问题
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